From 60211ae82912c96c48e85a3f8646188fe7a2de52 Mon Sep 17 00:00:00 2001 From: Randa Firman Putra Date: Sun, 14 Sep 2025 16:59:31 +0700 Subject: [PATCH] testing yuk --- .../data-beasiswa-mahasiswa/route.ts | 38 +++++----- .../data-beasiswa-mahasiswa/upload/route.ts | 72 +++++++++---------- .../data-kelompok-keahlian/route.ts | 14 ++-- app/api/keloladata/data-mahasiswa/route.ts | 26 +++---- .../keloladata/data-mahasiswa/upload/route.ts | 24 +++---- .../data-prestasi-mahasiswa/route.ts | 8 +-- .../data-prestasi-mahasiswa/upload/route.ts | 12 ++-- app/api/keloladata/kelompok-keahlian/route.ts | 18 ++--- .../setting-jenis-pendaftaran/route.ts | 10 +-- app/api/keloladata/update-semester/route.ts | 10 +-- .../mahasiswa/asal-daerah-angkatan/route.ts | 6 +- .../mahasiswa/asal-daerah-beasiswa/route.ts | 4 +- app/api/mahasiswa/asal-daerah-lulus/route.ts | 6 +- .../mahasiswa/asal-daerah-prestasi/route.ts | 4 +- app/api/mahasiswa/asal-daerah-status/route.ts | 6 +- app/api/mahasiswa/asal-daerah/route.ts | 4 +- .../mahasiswa/gender-per-angkatan/route.ts | 4 +- app/api/mahasiswa/ipk-beasiswa/route.ts | 6 +- app/api/mahasiswa/ipk-lulus-tepat/route.ts | 6 +- app/api/mahasiswa/ipk-prestasi/route.ts | 6 +- app/api/mahasiswa/ipk-status/route.ts | 6 +- app/api/mahasiswa/ipk/route.ts | 4 +- app/api/mahasiswa/jenis-beasiswa/route.ts | 2 +- .../jenis-pendaftaran-beasiswa/route.ts | 4 +- .../jenis-pendaftaran-lulus/route.ts | 6 +- .../jenis-pendaftaran-prestasi/route.ts | 4 +- .../jenis-pendaftaran-status/route.ts | 6 +- app/api/mahasiswa/jenis-pendaftaran/route.ts | 6 +- app/api/mahasiswa/jenis-prestasi/route.ts | 2 +- .../kelompok-keahlian-status/route.ts | 6 +- app/api/mahasiswa/kk-dashboard-tepat/route.ts | 8 +-- app/api/mahasiswa/kk-dashboard/route.ts | 6 +- app/api/mahasiswa/lulus-tepat-waktu/route.ts | 6 +- app/api/mahasiswa/masa-studi-aktif/route.ts | 6 +- app/api/mahasiswa/masa-studi-status/route.ts | 6 +- .../nama-beasiswa-dashboard/route.ts | 4 +- app/api/mahasiswa/nama-beasiswa/route.ts | 4 +- app/api/mahasiswa/profile/route.ts | 14 ++-- app/api/mahasiswa/provinsi-mahasiswa/route.ts | 6 +- app/api/mahasiswa/statistik/route.ts | 6 +- app/api/mahasiswa/status-kuliah/route.ts | 4 +- app/api/mahasiswa/status-mahasiswa/route.ts | 6 +- app/api/mahasiswa/status/route.ts | 4 +- app/api/mahasiswa/tahun-angkatan/route.ts | 6 +- .../tingkat-prestasi-dashboard/route.ts | 12 ++-- app/api/mahasiswa/tingkat-prestasi/route.ts | 18 ++--- app/api/mahasiswa/total-beasiswa/route.ts | 6 +- app/api/mahasiswa/total-prestasi/route.ts | 4 +- app/api/mahasiswa/total/route.ts | 18 ++--- components/charts/AsalDaerahBeasiswaChart.tsx | 10 +-- components/charts/AsalDaerahChart.tsx | 18 ++--- components/charts/AsalDaerahLulusChart.tsx | 10 +-- .../charts/AsalDaerahPerAngkatanChart.tsx | 18 ++--- components/charts/AsalDaerahPrestasiChart.tsx | 10 +-- components/charts/AsalDaerahStatusChart.tsx | 12 ++-- components/charts/IPKBeasiswaChart.tsx | 10 +-- components/charts/IPKChart.tsx | 12 ++-- components/charts/IPKJenisKelaminChart.tsx | 6 +- components/charts/IPKLulusTepatChart.tsx | 10 +-- components/charts/IPKPrestasiChart.tsx | 12 ++-- components/charts/IpkStatusChart.tsx | 12 ++-- components/charts/StatistikMahasiswaChart.tsx | 8 +-- .../charts/StatistikPerAngkatanChart.tsx | 8 +-- 63 files changed, 315 insertions(+), 315 deletions(-) diff --git a/app/api/keloladata/data-beasiswa-mahasiswa/route.ts b/app/api/keloladata/data-beasiswa-mahasiswa/route.ts index 0dd1563..9167f21 100644 --- a/app/api/keloladata/data-beasiswa-mahasiswa/route.ts +++ b/app/api/keloladata/data-beasiswa-mahasiswa/route.ts @@ -1,7 +1,7 @@ import { NextRequest, NextResponse } from 'next/server'; import supabase from '@/lib/db'; -// GET - Fetch all beasiswa mahasiswa or filter by criteria +// GET - Ambil semua data beasiswa mahasiswa atau filter berdasarkan kriteria export async function GET(request: NextRequest) { try { const { searchParams } = new URL(request.url); @@ -10,7 +10,7 @@ export async function GET(request: NextRequest) { const search = searchParams.get('search'); const jenisBeasiswa = searchParams.get('jenis_beasiswa'); - // If ID is provided, fetch specific beasiswa by ID with join + // Jika ID diberikan, ambil data beasiswa spesifik berdasarkan ID dengan join if (id) { const { data, error } = await supabase .from('beasiswa_mahasiswa') @@ -25,7 +25,7 @@ export async function GET(request: NextRequest) { return NextResponse.json({ message: 'Beasiswa mahasiswa not found' }, { status: 404 }); } - // Transform the data to flatten the nama and nim fields + // Transformasi data untuk meratakan field nama dan nim const transformedData = { ...data, nama: data.mahasiswa.nama, @@ -36,7 +36,7 @@ export async function GET(request: NextRequest) { return NextResponse.json(transformedData); } - // If id_mahasiswa is provided, fetch beasiswa for specific student with join + // Jika id_mahasiswa diberikan, ambil data beasiswa untuk mahasiswa spesifik dengan join if (id_mahasiswa) { const { data, error } = await supabase .from('beasiswa_mahasiswa') @@ -52,7 +52,7 @@ export async function GET(request: NextRequest) { return NextResponse.json({ message: 'Internal Server Error' }, { status: 500 }); } - // Transform the data to flatten the nama and nim fields + // Transformasi data untuk meratakan field nama dan nim const transformedData = data.map(item => ({ ...item, nama: item.mahasiswa.nama, @@ -62,26 +62,26 @@ export async function GET(request: NextRequest) { return NextResponse.json(transformedData); } - // Build the query based on filters with join + // Bangun query berdasarkan filter dengan join let query = supabase.from('beasiswa_mahasiswa').select(` *, mahasiswa!inner(nama, nim) `); - // Add search condition if provided + // Tambahkan kondisi pencarian jika diberikan if (search) { query = query.or(`mahasiswa.nama.ilike.%${search}%,mahasiswa.nim.ilike.%${search}%,nama_beasiswa.ilike.%${search}%,sumber_beasiswa.ilike.%${search}%`); } - // Add jenis_beasiswa filter if provided + // Tambahkan filter jenis_beasiswa jika diberikan if (jenisBeasiswa) { query = query.eq('jenis_beasiswa', jenisBeasiswa); } - // Add order by + // Tambahkan pengurutan query = query.order('created_at', { ascending: false }); - // Execute the query + // Eksekusi query const { data, error } = await query; if (error) { @@ -89,7 +89,7 @@ export async function GET(request: NextRequest) { return NextResponse.json({ message: 'Internal Server Error' }, { status: 500 }); } - // Transform the data to flatten the nama and nim fields + // Transformasi data untuk meratakan field nama dan nim const transformedData = data.map(item => ({ ...item, nama: item.mahasiswa.nama, @@ -103,7 +103,7 @@ export async function GET(request: NextRequest) { } } -// POST - Create a new beasiswa mahasiswa +// POST - Buat data beasiswa mahasiswa baru export async function POST(request: NextRequest) { try { const body = await request.json(); @@ -122,7 +122,7 @@ export async function POST(request: NextRequest) { ); } - // Check if mahasiswa exists by NIM and get id_mahasiswa + // Cek apakah mahasiswa ada berdasarkan NIM dan ambil id_mahasiswa const { data: mahasiswaExists, error: checkError } = await supabase .from('mahasiswa') .select('id_mahasiswa, nama') @@ -146,7 +146,7 @@ export async function POST(request: NextRequest) { ); } - // Insert new beasiswa using id_mahasiswa + // Insert data beasiswa baru menggunakan id_mahasiswa const { data, error } = await supabase .from('beasiswa_mahasiswa') .insert({ @@ -176,7 +176,7 @@ export async function POST(request: NextRequest) { } } -// PUT - Update an existing beasiswa mahasiswa +// PUT - Update data beasiswa mahasiswa yang sudah ada export async function PUT(request: NextRequest) { try { const { searchParams } = new URL(request.url); @@ -202,7 +202,7 @@ export async function PUT(request: NextRequest) { ); } - // Check if beasiswa exists + // Cek apakah beasiswa ada const { data: existing, error: checkError } = await supabase .from('beasiswa_mahasiswa') .select('*') @@ -237,7 +237,7 @@ export async function PUT(request: NextRequest) { ); } - // Update beasiswa using id_mahasiswa + // Update beasiswa menggunakan id_mahasiswa const { error } = await supabase .from('beasiswa_mahasiswa') .update({ @@ -262,7 +262,7 @@ export async function PUT(request: NextRequest) { } } -// DELETE - Delete a beasiswa mahasiswa +// DELETE - Hapus data beasiswa mahasiswa export async function DELETE(request: NextRequest) { try { const { searchParams } = new URL(request.url); @@ -283,7 +283,7 @@ export async function DELETE(request: NextRequest) { return NextResponse.json({ message: 'Beasiswa mahasiswa not found' }, { status: 404 }); } - // Delete beasiswa + // Hapus beasiswa const { error } = await supabase .from('beasiswa_mahasiswa') .delete() diff --git a/app/api/keloladata/data-beasiswa-mahasiswa/upload/route.ts b/app/api/keloladata/data-beasiswa-mahasiswa/upload/route.ts index b19eccc..05e89ae 100644 --- a/app/api/keloladata/data-beasiswa-mahasiswa/upload/route.ts +++ b/app/api/keloladata/data-beasiswa-mahasiswa/upload/route.ts @@ -2,14 +2,14 @@ import { NextRequest, NextResponse } from 'next/server'; import * as XLSX from 'xlsx'; import supabase from '@/lib/db'; -// GET method for testing the route +// GET method untuk testing route export async function GET() { return NextResponse.json({ message: 'Upload route is working' }); } export async function POST(request: NextRequest) { try { - // Get form data from request + // Ambil form data dari request const formData = await request.formData(); const file = formData.get('file') as File; @@ -17,23 +17,23 @@ export async function POST(request: NextRequest) { return NextResponse.json({ message: 'File tidak ditemukan' }, { status: 400 }); } - // Validate file size (max 10MB) + // Validasi ukuran file (maksimal 10MB) if (file.size > 10 * 1024 * 1024) { return NextResponse.json({ message: 'File terlalu besar. Maksimal 10MB' }, { status: 400 }); } - // Process file data based on file type + // Proses data file berdasarkan tipe file let validData = []; let errors: string[] = []; if (file.name.endsWith('.csv') || file.type === 'text/csv') { - // Process as CSV + // Proses sebagai CSV const fileContent = await file.text(); const result = await processCSVData(fileContent); validData = result.validData; errors = result.errors; } else { - // Process as Excel + // Proses sebagai Excel const fileBuffer = await file.arrayBuffer(); const result = await processExcelData(fileBuffer); validData = result.validData; @@ -47,10 +47,10 @@ export async function POST(request: NextRequest) { }, { status: 400 }); } - // Insert valid data into the database + // Insert data valid ke database const { imported, errorCount, errorMessages } = await insertDataToDatabase(validData); - // Combine all error messages + // Gabungkan semua pesan error const allErrors = [...errors, ...errorMessages]; return NextResponse.json({ @@ -69,17 +69,17 @@ export async function POST(request: NextRequest) { } } -// Function to process Excel data +// Fungsi untuk memproses data Excel async function processExcelData(fileBuffer: ArrayBuffer) { try { - // Parse Excel file + // Parse file Excel const workbook = XLSX.read(fileBuffer, { type: 'array' }); if (!workbook.SheetNames || workbook.SheetNames.length === 0) { return { validData: [], errors: ['File Excel tidak memiliki sheet'] }; } - // Get first sheet + // Ambil sheet pertama const sheetName = workbook.SheetNames[0]; const worksheet = workbook.Sheets[sheetName]; @@ -87,7 +87,7 @@ async function processExcelData(fileBuffer: ArrayBuffer) { return { validData: [], errors: ['Sheet pertama tidak ditemukan'] }; } - // Convert to JSON with proper typing + // Konversi ke JSON dengan tipe yang tepat const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 }) as any[][]; if (jsonData.length === 0) { @@ -98,11 +98,11 @@ async function processExcelData(fileBuffer: ArrayBuffer) { return { validData: [], errors: ['File Excel hanya memiliki header, tidak ada data'] }; } - // Convert Excel data to CSV-like format for processing + // Konversi data Excel ke format seperti CSV untuk diproses const headers = jsonData[0].map(h => String(h).toLowerCase()); const rows = jsonData.slice(1); - // Process the data using the common function + // Proses data menggunakan fungsi yang sama return processData(headers, rows); } catch (error) { console.error('Error processing Excel data:', error); @@ -110,7 +110,7 @@ async function processExcelData(fileBuffer: ArrayBuffer) { } } -// Function to process CSV data +// Fungsi untuk memproses data CSV async function processCSVData(fileContent: string) { const lines = fileContent.split(/\r?\n/).filter(line => line.trim() !== ''); @@ -118,19 +118,19 @@ async function processCSVData(fileContent: string) { return { validData: [], errors: ['File CSV kosong'] }; } - // Get headers from first line + // Ambil header dari baris pertama const headerLine = lines[0].toLowerCase(); const headers = headerLine.split(',').map(h => h.trim()); - // Process data rows + // Proses baris data const rows = lines.slice(1).map(line => line.split(',').map(v => v.trim())); return processData(headers, rows); } -// Common function to process data regardless of source format +// Fungsi umum untuk memproses data terlepas dari format sumber function processData(headers: string[], rows: any[][]) { - // Define expected headers and their possible variations + // Definisikan header yang diharapkan dan variasi yang mungkin const expectedHeaderMap = { nim: ['nim', 'nomor induk', 'nomor mahasiswa'], nama_beasiswa: ['nama_beasiswa', 'nama beasiswa', 'namabeasiswa', 'beasiswa', 'nama'], @@ -138,7 +138,7 @@ function processData(headers: string[], rows: any[][]) { jenis_beasiswa: ['jenis_beasiswa', 'jenis beasiswa', 'jenisbeasiswa', 'jenis'] }; - // Map actual headers to expected headers + // Map header aktual ke header yang diharapkan const headerMap: { [key: string]: number } = {}; for (const [expectedHeader, variations] of Object.entries(expectedHeaderMap)) { const index = headers.findIndex(h => @@ -149,7 +149,7 @@ function processData(headers: string[], rows: any[][]) { } } - // Check required headers + // Cek header yang wajib ada const requiredHeaders = ['nim', 'nama_beasiswa', 'sumber_beasiswa', 'jenis_beasiswa']; const missingHeaders = requiredHeaders.filter(h => headerMap[h] === undefined); @@ -164,34 +164,34 @@ function processData(headers: string[], rows: any[][]) { const errors = []; const validJenis = ['Pemerintah', 'Non-Pemerintah']; - // Process data rows + // Proses baris data for (let i = 0; i < rows.length; i++) { const values = rows[i]; if (!values || values.length === 0) continue; try { - // Extract values using header map + // Ekstrak nilai menggunakan header map const nim = String(values[headerMap.nim] || '').trim(); const nama_beasiswa = String(values[headerMap.nama_beasiswa] || '').trim(); const sumber_beasiswa = String(values[headerMap.sumber_beasiswa] || '').trim(); let jenis_beasiswa = String(values[headerMap.jenis_beasiswa] || '').trim(); - // Validate required fields + // Validasi field yang wajib diisi if (!nim || !nama_beasiswa || !sumber_beasiswa || !jenis_beasiswa) { errors.push(`Baris ${i+2}: Data tidak lengkap (NIM: ${nim || 'kosong'})`); continue; } - // Normalize jenis beasiswa + // Normalisasi jenis beasiswa jenis_beasiswa = normalizeJenisBeasiswa(jenis_beasiswa); - // Validate jenis beasiswa + // Validasi jenis beasiswa if (!validJenis.includes(jenis_beasiswa)) { errors.push(`Baris ${i+2}: Jenis beasiswa tidak valid "${jenis_beasiswa}" untuk NIM ${nim}. Harus salah satu dari: ${validJenis.join(', ')}`); continue; } - // Add to valid data + // Tambahkan ke data valid validData.push({ nim, nama_beasiswa, @@ -207,7 +207,7 @@ function processData(headers: string[], rows: any[][]) { return { validData, errors }; } -// Function to normalize jenis beasiswa values +// Fungsi untuk menormalisasi nilai jenis beasiswa function normalizeJenisBeasiswa(value: string): string { const lowerValue = value.toLowerCase(); @@ -219,20 +219,20 @@ function normalizeJenisBeasiswa(value: string): string { return 'Non-Pemerintah'; } - return value; // Return original if no match + return value; // Return original jika tidak ada match } -// Function to insert data into database +// Fungsi untuk insert data ke database async function insertDataToDatabase(data: any[]) { let imported = 0; let errorCount = 0; const errorMessages: string[] = []; - // First, validate all NIMs exist before processing + // Pertama, validasi semua NIM ada sebelum diproses const uniqueNims = [...new Set(data.map(item => item.nim))]; const nimValidationMap = new Map(); - // Batch check all NIMs for existence + // Cek batch semua NIM untuk keberadaan for (const nim of uniqueNims) { try { const { data: mahasiswaData, error: checkError } = await supabase @@ -251,7 +251,7 @@ async function insertDataToDatabase(data: any[]) { } } - // Process each data item + // Proses setiap item data for (const item of data) { try { const nimValidation = nimValidationMap.get(item.nim); @@ -263,7 +263,7 @@ async function insertDataToDatabase(data: any[]) { continue; } - // Check if beasiswa already exists for this mahasiswa and nama_beasiswa + // Cek apakah beasiswa sudah ada untuk mahasiswa ini dan nama_beasiswa const { data: existingBeasiswa, error: beasiswaCheckError } = await supabase .from('beasiswa_mahasiswa') .select('id_beasiswa') @@ -272,7 +272,7 @@ async function insertDataToDatabase(data: any[]) { .single(); if (existingBeasiswa) { - // Update existing beasiswa + // Update beasiswa yang sudah ada const { error: updateError } = await supabase .from('beasiswa_mahasiswa') .update({ @@ -288,7 +288,7 @@ async function insertDataToDatabase(data: any[]) { continue; } } else { - // Insert new beasiswa + // Insert beasiswa baru const { error: insertError } = await supabase .from('beasiswa_mahasiswa') .insert({ diff --git a/app/api/keloladata/data-kelompok-keahlian/route.ts b/app/api/keloladata/data-kelompok-keahlian/route.ts index c0c31fb..d8e7bc7 100644 --- a/app/api/keloladata/data-kelompok-keahlian/route.ts +++ b/app/api/keloladata/data-kelompok-keahlian/route.ts @@ -1,7 +1,7 @@ import { NextRequest, NextResponse } from "next/server"; import supabase from "@/lib/db"; -// GET - Fetch all kelompok keahlian +// GET - Ambil semua data kelompok keahlian export async function GET() { try { const { data, error } = await supabase @@ -23,12 +23,12 @@ export async function GET() { } } -// POST - Create new kelompok keahlian +// POST - Buat kelompok keahlian baru export async function POST(request: NextRequest) { try { const { nama_kelompok } = await request.json(); - // Validation + // Validasi if (!nama_kelompok) { return NextResponse.json( { error: "nama_kelompok is required" }, @@ -36,7 +36,7 @@ export async function POST(request: NextRequest) { ); } - // Check if nama_kelompok already exists + // Cek apakah nama_kelompok sudah ada const { data: existingKelompok, error: checkError } = await supabase .from('kelompok_keahlian') .select('id_kk') @@ -74,7 +74,7 @@ export async function POST(request: NextRequest) { } } -// PUT - Update kelompok keahlian +// PUT - Update data kelompok keahlian export async function PUT(request: NextRequest) { try { const { id_kk, nama_kelompok } = await request.json(); @@ -87,7 +87,7 @@ export async function PUT(request: NextRequest) { ); } - // Check if kelompok keahlian exists + // Cek apakah kelompok keahlian ada const { data: existingKelompok, error: checkError } = await supabase .from('kelompok_keahlian') .select('id_kk') @@ -105,7 +105,7 @@ export async function PUT(request: NextRequest) { ); } - // Check if nama_kelompok already exists for another kelompok + // Cek apakah nama_kelompok sudah ada untuk kelompok lain const { data: duplicateNama, error: duplicateError } = await supabase .from('kelompok_keahlian') .select('id_kk') diff --git a/app/api/keloladata/data-mahasiswa/route.ts b/app/api/keloladata/data-mahasiswa/route.ts index 8789fd8..a8a59fc 100644 --- a/app/api/keloladata/data-mahasiswa/route.ts +++ b/app/api/keloladata/data-mahasiswa/route.ts @@ -1,14 +1,14 @@ import { NextRequest, NextResponse } from 'next/server'; import supabase from '@/lib/db'; -// GET - Fetch all mahasiswa or a specific one by NIM +// GET - Ambil semua data mahasiswa atau satu mahasiswa spesifik berdasarkan NIM export async function GET(request: NextRequest) { try { const { searchParams } = new URL(request.url); const nim = searchParams.get('nim'); if (nim) { - // Fetch specific mahasiswa by NIM with joins + // Ambil mahasiswa spesifik berdasarkan NIM dengan join const { data, error } = await supabase .from('mahasiswa') .select(` @@ -22,7 +22,7 @@ export async function GET(request: NextRequest) { return NextResponse.json({ message: 'Mahasiswa not found' }, { status: 404 }); } - // Transform the data to flatten the joined fields + // Transformasi data untuk meratakan field yang di-join const transformedData = { ...data, nama_kelompok_keahlian: data.kelompok_keahlian?.nama_kelompok || null @@ -31,7 +31,7 @@ export async function GET(request: NextRequest) { return NextResponse.json(transformedData); } else { - // Fetch all mahasiswa with joins + // Ambil semua mahasiswa dengan join const { data, error } = await supabase .from('mahasiswa') .select(` @@ -45,7 +45,7 @@ export async function GET(request: NextRequest) { return NextResponse.json({ message: 'Internal Server Error' }, { status: 500 }); } - // Transform the data to flatten the joined fields + // Transformasi data untuk meratakan field yang di-join const transformedData = data.map(item => ({ ...item, nama_kelompok_keahlian: item.kelompok_keahlian?.nama_kelompok || null @@ -59,7 +59,7 @@ export async function GET(request: NextRequest) { } } -// POST - Create a new mahasiswa +// POST - Buat data mahasiswa baru export async function POST(request: NextRequest) { try { const body = await request.json(); @@ -78,7 +78,7 @@ export async function POST(request: NextRequest) { semester } = body; - // Validate required fields + // Validasi field yang wajib diisi if (!nim || !nama || !jk || !tahun_angkatan) { return NextResponse.json( { message: 'Missing required fields: nim, nama, jk, tahun_angkatan' }, @@ -86,7 +86,7 @@ export async function POST(request: NextRequest) { ); } - // Check if mahasiswa already exists + // Cek apakah mahasiswa sudah ada const { data: existing, error: checkError } = await supabase .from('mahasiswa') .select('nim') @@ -100,7 +100,7 @@ export async function POST(request: NextRequest) { ); } - // Insert new mahasiswa + // Insert mahasiswa baru const { data, error } = await supabase .from('mahasiswa') .insert({ @@ -135,7 +135,7 @@ export async function POST(request: NextRequest) { } } -// PUT - Update an existing mahasiswa +// PUT - Update data mahasiswa yang sudah ada export async function PUT(request: NextRequest) { try { const { searchParams } = new URL(request.url); @@ -160,7 +160,7 @@ export async function PUT(request: NextRequest) { semester } = body; - // Check if mahasiswa exists + // Cek apakah mahasiswa ada const { data: existing, error: checkError } = await supabase .from('mahasiswa') .select('*') @@ -201,7 +201,7 @@ export async function PUT(request: NextRequest) { } } -// DELETE - Delete a mahasiswa +// DELETE - Hapus data mahasiswa export async function DELETE(request: NextRequest) { try { const { searchParams } = new URL(request.url); @@ -222,7 +222,7 @@ export async function DELETE(request: NextRequest) { return NextResponse.json({ message: 'Mahasiswa not found' }, { status: 404 }); } - // Delete mahasiswa + // Hapus mahasiswa const { error } = await supabase .from('mahasiswa') .delete() diff --git a/app/api/keloladata/data-mahasiswa/upload/route.ts b/app/api/keloladata/data-mahasiswa/upload/route.ts index 1d873bd..c0bcace 100644 --- a/app/api/keloladata/data-mahasiswa/upload/route.ts +++ b/app/api/keloladata/data-mahasiswa/upload/route.ts @@ -4,7 +4,7 @@ import * as XLSX from 'xlsx'; export async function POST(request: NextRequest) { try { - // Get form data from request + // Ambil form data dari request const formData = await request.formData(); const file = formData.get('file') as File; @@ -12,21 +12,21 @@ export async function POST(request: NextRequest) { return NextResponse.json({ message: 'No file uploaded' }, { status: 400 }); } - // Read file content as array buffer + // Baca konten file sebagai array buffer const fileBuffer = await file.arrayBuffer(); - // Process file data based on file type + // Proses data file berdasarkan tipe file let validData = []; let errors: string[] = []; if (file.name.endsWith('.csv') || file.type === 'text/csv') { - // Process as CSV + // Proses sebagai CSV const fileContent = await file.text(); const result = await processCSVData(fileContent); validData = result.validData; errors = result.errors; } else { - // Process as Excel + // Proses sebagai Excel const result = await processExcelData(fileBuffer); validData = result.validData; errors = result.errors; @@ -39,7 +39,7 @@ export async function POST(request: NextRequest) { }, { status: 400 }); } - // Insert valid data into the database + // Insert data valid ke database const { insertedCount, errorCount } = await insertDataToDatabase(validData); return NextResponse.json({ @@ -58,7 +58,7 @@ export async function POST(request: NextRequest) { } } -// Function to process Excel data +// Fungsi untuk memproses data Excel async function processExcelData(fileBuffer: ArrayBuffer) { try { // Parse Excel file @@ -87,7 +87,7 @@ async function processExcelData(fileBuffer: ArrayBuffer) { } } -// Function to process CSV data +// Fungsi untuk memproses data CSV async function processCSVData(fileContent: string) { const lines = fileContent.split(/\r?\n/).filter(line => line.trim() !== ''); @@ -301,14 +301,14 @@ function mapStatus(value: string): 'Aktif' | 'Cuti' | 'Lulus' | 'Non-Aktif' | nu return null; } -// Function to insert data into database +// Fungsi untuk insert data ke database async function insertDataToDatabase(data: any[]) { let insertedCount = 0; let errorCount = 0; for (const item of data) { try { - // Check if mahasiswa already exists + // Cek apakah mahasiswa sudah ada const { data: existingData } = await supabase .from('mahasiswa') .select('nim') @@ -330,7 +330,7 @@ async function insertDataToDatabase(data: any[]) { }; if (existingData) { - // Update existing record + // Update record yang sudah ada const { error } = await supabase .from('mahasiswa') .update(mahasiswaData) @@ -338,7 +338,7 @@ async function insertDataToDatabase(data: any[]) { if (error) throw error; } else { - // Insert new record + // Insert record baru const { error } = await supabase .from('mahasiswa') .insert({ diff --git a/app/api/keloladata/data-prestasi-mahasiswa/route.ts b/app/api/keloladata/data-prestasi-mahasiswa/route.ts index 9806244..dd1f427 100644 --- a/app/api/keloladata/data-prestasi-mahasiswa/route.ts +++ b/app/api/keloladata/data-prestasi-mahasiswa/route.ts @@ -1,7 +1,7 @@ import { NextRequest, NextResponse } from 'next/server'; import supabase from '@/lib/db'; -// GET - Fetch all prestasi mahasiswa or filter by criteria +// GET - Ambil semua data prestasi mahasiswa atau filter berdasarkan kriteria export async function GET(request: NextRequest) { try { const { searchParams } = new URL(request.url); @@ -109,7 +109,7 @@ export async function GET(request: NextRequest) { } } -// POST - Create a new prestasi mahasiswa +// POST - Buat data prestasi mahasiswa baru export async function POST(request: NextRequest) { try { const body = await request.json(); @@ -196,7 +196,7 @@ export async function POST(request: NextRequest) { } } -// PUT - Update an existing prestasi mahasiswa +// PUT - Update data prestasi mahasiswa yang sudah ada export async function PUT(request: NextRequest) { try { const { searchParams } = new URL(request.url); @@ -296,7 +296,7 @@ export async function PUT(request: NextRequest) { } } -// DELETE - Delete a prestasi mahasiswa +// DELETE - Hapus data prestasi mahasiswa export async function DELETE(request: NextRequest) { try { const { searchParams } = new URL(request.url); diff --git a/app/api/keloladata/data-prestasi-mahasiswa/upload/route.ts b/app/api/keloladata/data-prestasi-mahasiswa/upload/route.ts index a28130f..9025ac8 100644 --- a/app/api/keloladata/data-prestasi-mahasiswa/upload/route.ts +++ b/app/api/keloladata/data-prestasi-mahasiswa/upload/route.ts @@ -334,14 +334,14 @@ async function insertDataToDatabase(data: any[]) { console.log(`Total data items to process: ${data.length}`); console.log('Sample data items:', data.slice(0, 3)); - // First, validate all NIMs exist before processing + // Pertama, validasi semua NIM ada sebelum diproses const uniqueNims = [...new Set(data.map(item => item.nim))]; console.log(`Unique NIMs found: ${uniqueNims.length}`); console.log('Unique NIMs:', uniqueNims); const nimValidationMap = new Map(); - // Batch check all NIMs for existence + // Cek batch semua NIM untuk keberadaan console.log('=== DEBUG: Starting NIM validation ==='); for (const nim of uniqueNims) { try { @@ -370,7 +370,7 @@ async function insertDataToDatabase(data: any[]) { console.log('=== DEBUG: NIM validation results ==='); console.log('Validation map:', Object.fromEntries(nimValidationMap)); - // Process each data item + // Proses setiap item data console.log('=== DEBUG: Starting prestasi data processing ==='); for (const item of data) { try { @@ -390,7 +390,7 @@ async function insertDataToDatabase(data: any[]) { console.log(`✅ NIM ${item.nim} is valid, proceeding with prestasi check/insert`); - // Check if prestasi already exists for this mahasiswa + // Cek apakah prestasi sudah ada untuk mahasiswa ini console.log(`Checking existing prestasi for mahasiswa ID: ${nimValidation.id_mahasiswa}, nama_prestasi: ${item.nama_prestasi}, tanggal: ${item.tanggal_prestasi}`); const { data: existingPrestasi, error: prestasiCheckError } = await supabase .from('prestasi_mahasiswa') @@ -406,7 +406,7 @@ async function insertDataToDatabase(data: any[]) { if (existingPrestasi) { console.log(`📝 Updating existing prestasi (ID: ${existingPrestasi.id_prestasi})`); - // Update existing prestasi + // Update prestasi yang sudah ada const { error: updateError } = await supabase .from('prestasi_mahasiswa') .update({ @@ -428,7 +428,7 @@ async function insertDataToDatabase(data: any[]) { } } else { console.log(`📝 Inserting new prestasi for mahasiswa ID: ${nimValidation.id_mahasiswa}`); - // Insert new prestasi + // Insert prestasi baru const { error: insertError } = await supabase .from('prestasi_mahasiswa') .insert({ diff --git a/app/api/keloladata/kelompok-keahlian/route.ts b/app/api/keloladata/kelompok-keahlian/route.ts index 403d583..d9630cd 100644 --- a/app/api/keloladata/kelompok-keahlian/route.ts +++ b/app/api/keloladata/kelompok-keahlian/route.ts @@ -1,7 +1,7 @@ import { NextRequest, NextResponse } from 'next/server'; import supabase from '@/lib/db'; -// GET - Get all kelompok keahlian +// GET - Ambil semua data kelompok keahlian export async function GET() { try { const { data, error } = await supabase @@ -27,7 +27,7 @@ export async function GET() { } } -// POST - Create new kelompok keahlian +// POST - Buat kelompok keahlian baru export async function POST(request: NextRequest) { try { const { nama_kelompok } = await request.json(); @@ -39,7 +39,7 @@ export async function POST(request: NextRequest) { ); } - // Check if nama_kelompok already exists + // Cek apakah nama_kelompok sudah ada const { data: existingData, error: existingError } = await supabase .from('kelompok_keahlian') .select('id_kk') @@ -60,7 +60,7 @@ export async function POST(request: NextRequest) { ); } - // Insert without specifying id_kk to let the database auto-generate it + // Insert tanpa menentukan id_kk untuk membiarkan database auto-generate const { data, error } = await supabase .from('kelompok_keahlian') .insert([{ nama_kelompok: nama_kelompok.trim() }]) @@ -85,7 +85,7 @@ export async function POST(request: NextRequest) { } } -// PUT - Update kelompok keahlian +// PUT - Update data kelompok keahlian export async function PUT(request: NextRequest) { try { const { id_kk, nama_kelompok } = await request.json(); @@ -111,7 +111,7 @@ export async function PUT(request: NextRequest) { ); } - // Check if nama_kelompok already exists for other records + // Cek apakah nama_kelompok sudah ada untuk record lain const { data: duplicateData, error: duplicateError } = await supabase .from('kelompok_keahlian') .select('id_kk') @@ -158,7 +158,7 @@ export async function PUT(request: NextRequest) { } } -// DELETE - Delete kelompok keahlian +// DELETE - Hapus kelompok keahlian export async function DELETE(request: NextRequest) { try { const { searchParams } = new URL(request.url); @@ -185,8 +185,8 @@ export async function DELETE(request: NextRequest) { ); } - // Check if kelompok keahlian is being used in other tables - // You might want to add foreign key checks here depending on your database structure + // Cek apakah kelompok keahlian sedang digunakan di tabel lain + // Anda mungkin ingin menambahkan cek foreign key di sini tergantung struktur database const { error } = await supabase .from('kelompok_keahlian') diff --git a/app/api/keloladata/setting-jenis-pendaftaran/route.ts b/app/api/keloladata/setting-jenis-pendaftaran/route.ts index 0aa4287..3ca60fd 100644 --- a/app/api/keloladata/setting-jenis-pendaftaran/route.ts +++ b/app/api/keloladata/setting-jenis-pendaftaran/route.ts @@ -1,10 +1,10 @@ import { NextRequest, NextResponse } from 'next/server'; import supabase from '@/lib/db'; -// GET - Fetch all unique jenis_pendaftaran values +// GET - Ambil semua nilai jenis_pendaftaran yang unik export async function GET() { try { - // Get all unique jenis_pendaftaran values + // Ambil semua nilai jenis_pendaftaran yang unik const { data, error } = await supabase .from('mahasiswa') .select('jenis_pendaftaran') @@ -16,7 +16,7 @@ export async function GET() { return NextResponse.json({ message: 'Internal Server Error' }, { status: 500 }); } - // Get unique values + // Ambil nilai unik const uniqueValues = [...new Set(data.map(item => item.jenis_pendaftaran))]; return NextResponse.json(uniqueValues.map(value => ({ jenis_pendaftaran: value }))); @@ -26,13 +26,13 @@ export async function GET() { } } -// PUT - Update jenis_pendaftaran value +// PUT - Update nilai jenis_pendaftaran export async function PUT(request: NextRequest) { try { const body = await request.json(); const { oldValue, newValue } = body; - // Validate required fields + // Validasi field yang wajib diisi if (!oldValue || !newValue) { return NextResponse.json( { message: 'Missing required fields: oldValue, newValue' }, diff --git a/app/api/keloladata/update-semester/route.ts b/app/api/keloladata/update-semester/route.ts index 3c10b94..454d951 100644 --- a/app/api/keloladata/update-semester/route.ts +++ b/app/api/keloladata/update-semester/route.ts @@ -3,12 +3,12 @@ import supabase from '@/lib/db'; export async function POST() { try { - // Get current date + // Ambil tanggal saat ini const currentDate = new Date(); const currentYear = currentDate.getFullYear(); const currentMonth = currentDate.getMonth() + 1; // getMonth() returns 0-11 - // Get all active students + // Ambil semua mahasiswa aktif const { data: activeStudents, error: fetchError } = await supabase .from('mahasiswa') .select('nim, tahun_angkatan, semester') @@ -32,7 +32,7 @@ export async function POST() { let updatedCount = 0; const errors: string[] = []; - // Update semester for each active student + // Update semester untuk setiap mahasiswa aktif for (const student of activeStudents) { try { const tahunAngkatan = student.tahun_angkatan; @@ -41,7 +41,7 @@ export async function POST() { continue; } - // Calculate current semester based on tahun_angkatan and current date + // Hitung semester saat ini berdasarkan tahun_angkatan dan tanggal saat ini const years = currentYear - tahunAngkatan; let currentSemester: number; @@ -60,7 +60,7 @@ export async function POST() { if (currentSemester < 1) currentSemester = 1; if (currentSemester > 14) currentSemester = 14; - // Update semester if different + // Update semester jika berbeda if (student.semester !== currentSemester) { const { error: updateError } = await supabase .from('mahasiswa') diff --git a/app/api/mahasiswa/asal-daerah-angkatan/route.ts b/app/api/mahasiswa/asal-daerah-angkatan/route.ts index adf83a0..be45889 100644 --- a/app/api/mahasiswa/asal-daerah-angkatan/route.ts +++ b/app/api/mahasiswa/asal-daerah-angkatan/route.ts @@ -38,20 +38,20 @@ export async function GET(request: Request) { ); } - // Group by kabupaten and count + // Kelompokkan berdasarkan kabupaten dan hitung const groupedData = data.reduce((acc, item) => { acc[item.kabupaten] = (acc[item.kabupaten] || 0) + 1; return acc; }, {} as Record); - // Convert to final format and sort + // Konversi ke format akhir dan urutkan const results: AsalDaerah[] = Object.entries(groupedData) .map(([kabupaten, jumlah]) => ({ kabupaten, jumlah })) .sort((a, b) => { - // Sort by jumlah DESC, then by kabupaten ASC + // Urutkan berdasarkan jumlah DESC, kemudian kabupaten ASC if (a.jumlah !== b.jumlah) { return b.jumlah - a.jumlah; } diff --git a/app/api/mahasiswa/asal-daerah-beasiswa/route.ts b/app/api/mahasiswa/asal-daerah-beasiswa/route.ts index f02afbf..e725e68 100644 --- a/app/api/mahasiswa/asal-daerah-beasiswa/route.ts +++ b/app/api/mahasiswa/asal-daerah-beasiswa/route.ts @@ -32,7 +32,7 @@ export async function GET(request: Request) { ); } - // Group and count the data in JavaScript + // Kelompokkan dan hitung data di JavaScript const groupedData = data.reduce((acc: any[], row: any) => { const tahunAngkatanValue = row.tahun_angkatan; const kabupaten = row.kabupaten; @@ -58,7 +58,7 @@ export async function GET(request: Request) { return acc; }, []); - // Sort the results + // Urutkan hasil const sortedData = groupedData.sort((a: any, b: any) => { if (a.tahun_angkatan !== b.tahun_angkatan) { return a.tahun_angkatan - b.tahun_angkatan; diff --git a/app/api/mahasiswa/asal-daerah-lulus/route.ts b/app/api/mahasiswa/asal-daerah-lulus/route.ts index 96e9131..c2e7f48 100644 --- a/app/api/mahasiswa/asal-daerah-lulus/route.ts +++ b/app/api/mahasiswa/asal-daerah-lulus/route.ts @@ -32,7 +32,7 @@ export async function GET(request: Request) { ); } - // Group by tahun_angkatan and kabupaten + // Kelompokkan berdasarkan tahun_angkatan dan kabupaten const groupedData = data.reduce((acc, item: any) => { const tahun_angkatan = item.tahun_angkatan; const kabupaten = item.kabupaten; @@ -41,7 +41,7 @@ export async function GET(request: Request) { return acc; }, {} as Record); - // Convert to final format and sort + // Konversi ke format akhir dan urutkan const results: AsalDaerahLulus[] = Object.entries(groupedData) .map(([key, jumlah_lulus_tepat_waktu]) => { const [tahun_angkatan, kabupaten] = key.split('-'); @@ -52,7 +52,7 @@ export async function GET(request: Request) { }; }) .sort((a, b) => { - // Sort by tahun_angkatan DESC, jumlah_lulus_tepat_waktu DESC + // Urutkan berdasarkan tahun_angkatan DESC, jumlah_lulus_tepat_waktu DESC if (a.tahun_angkatan !== b.tahun_angkatan) { return b.tahun_angkatan - a.tahun_angkatan; } diff --git a/app/api/mahasiswa/asal-daerah-prestasi/route.ts b/app/api/mahasiswa/asal-daerah-prestasi/route.ts index 6cb26b2..ba172d1 100644 --- a/app/api/mahasiswa/asal-daerah-prestasi/route.ts +++ b/app/api/mahasiswa/asal-daerah-prestasi/route.ts @@ -32,7 +32,7 @@ export async function GET(request: Request) { ); } - // Group and count the data in JavaScript + // Kelompokkan dan hitung data di JavaScript const groupedData = data.reduce((acc: any[], row: any) => { const tahunAngkatanValue = row.tahun_angkatan; const kabupaten = row.kabupaten; @@ -58,7 +58,7 @@ export async function GET(request: Request) { return acc; }, []); - // Sort the results + // Urutkan hasil const sortedData = groupedData.sort((a: any, b: any) => { if (a.tahun_angkatan !== b.tahun_angkatan) { return b.tahun_angkatan - a.tahun_angkatan; diff --git a/app/api/mahasiswa/asal-daerah-status/route.ts b/app/api/mahasiswa/asal-daerah-status/route.ts index c87d968..407dda6 100644 --- a/app/api/mahasiswa/asal-daerah-status/route.ts +++ b/app/api/mahasiswa/asal-daerah-status/route.ts @@ -41,7 +41,7 @@ export async function GET(request: Request) { ); } - // Group by kabupaten, tahun_angkatan (optional), status_kuliah + // Kelompokkan berdasarkan kabupaten, tahun_angkatan (opsional), status_kuliah const groupedData = data.reduce((acc, item: any) => { const kabupaten = item.kabupaten; const tahun_angkatan = tahunAngkatan && tahunAngkatan !== 'all' ? item.tahun_angkatan : undefined; @@ -53,7 +53,7 @@ export async function GET(request: Request) { return acc; }, {} as Record); - // Convert to final format and sort + // Konversi ke format akhir dan urutkan const results: AsalDaerahStatus[] = Object.entries(groupedData) .map(([key, total_mahasiswa]) => { const parts = key.split('-'); @@ -75,7 +75,7 @@ export async function GET(request: Request) { } }) .sort((a, b) => { - // Sort by tahun_angkatan ASC (if exists), kabupaten ASC, status_kuliah ASC + // Urutkan berdasarkan tahun_angkatan ASC (jika ada), kabupaten ASC, status_kuliah ASC if (a.tahun_angkatan !== undefined && b.tahun_angkatan !== undefined && a.tahun_angkatan !== b.tahun_angkatan) { return a.tahun_angkatan - b.tahun_angkatan; } diff --git a/app/api/mahasiswa/asal-daerah/route.ts b/app/api/mahasiswa/asal-daerah/route.ts index d4414f0..1aee5cb 100644 --- a/app/api/mahasiswa/asal-daerah/route.ts +++ b/app/api/mahasiswa/asal-daerah/route.ts @@ -28,14 +28,14 @@ export async function GET() { ); } - // Group by kabupaten and count + // Kelompokkan berdasarkan kabupaten dan hitung const groupedData = data.reduce((acc, item) => { const kabupaten = item.kabupaten; acc[kabupaten] = (acc[kabupaten] || 0) + 1; return acc; }, {} as Record); - // Convert to array format + // Konversi ke format array const results: AsalDaerah[] = Object.entries(groupedData).map(([kabupaten, jumlah]) => ({ kabupaten, jumlah diff --git a/app/api/mahasiswa/gender-per-angkatan/route.ts b/app/api/mahasiswa/gender-per-angkatan/route.ts index f1437ec..4d3e1fd 100644 --- a/app/api/mahasiswa/gender-per-angkatan/route.ts +++ b/app/api/mahasiswa/gender-per-angkatan/route.ts @@ -39,13 +39,13 @@ export async function GET(request: Request) { ); } - // Group by jk and count + // Kelompokkan berdasarkan jk dan hitung const groupedData = data.reduce((acc, item) => { acc[item.jk] = (acc[item.jk] || 0) + 1; return acc; }, {} as Record); - // Convert to final format + // Konversi ke format akhir const results: GenderData[] = Object.entries(groupedData).map(([jk, jumlah]) => ({ tahun_angkatan: parseInt(tahun), jk, diff --git a/app/api/mahasiswa/ipk-beasiswa/route.ts b/app/api/mahasiswa/ipk-beasiswa/route.ts index 6b36e6d..1f404c7 100644 --- a/app/api/mahasiswa/ipk-beasiswa/route.ts +++ b/app/api/mahasiswa/ipk-beasiswa/route.ts @@ -25,7 +25,7 @@ export async function GET(request: Request) { ); } - // Group and calculate statistics in JavaScript + // Kelompokkan dan hitung statistik di JavaScript const groupedData = data.reduce((acc: any[], row: any) => { const tahunAngkatan = row.tahun_angkatan; const ipk = row.ipk; @@ -50,14 +50,14 @@ export async function GET(request: Request) { return acc; }, []); - // Calculate average IPK and format the results + // Hitung rata-rata IPK dan format hasil const result = groupedData.map((group: any) => ({ tahun_angkatan: group.tahun_angkatan, total_mahasiswa_beasiswa: group.total_mahasiswa_beasiswa, rata_rata_ipk: Math.round((group.total_ipk / group.total_mahasiswa_beasiswa) * 100) / 100 })); - // Sort by tahun_angkatan ascending + // Urutkan berdasarkan tahun_angkatan ascending const sortedData = result.sort((a: any, b: any) => a.tahun_angkatan - b.tahun_angkatan); return NextResponse.json(sortedData); diff --git a/app/api/mahasiswa/ipk-lulus-tepat/route.ts b/app/api/mahasiswa/ipk-lulus-tepat/route.ts index 206a532..2075a23 100644 --- a/app/api/mahasiswa/ipk-lulus-tepat/route.ts +++ b/app/api/mahasiswa/ipk-lulus-tepat/route.ts @@ -32,7 +32,7 @@ export async function GET(request: Request) { ); } - // Group by tahun_angkatan and calculate average IPK + // Kelompokkan berdasarkan tahun_angkatan dan hitung rata-rata IPK const groupedData = data.reduce((acc, item: any) => { const tahun_angkatan = item.tahun_angkatan; const ipk = item.ipk; @@ -50,14 +50,14 @@ export async function GET(request: Request) { return acc; }, {} as Record); - // Convert to final format and sort + // Konversi ke format akhir dan urutkan const results: IpkLulusTepat[] = Object.entries(groupedData) .map(([tahun_angkatan, data]) => ({ tahun_angkatan: parseInt(tahun_angkatan), rata_rata_ipk: Math.round((data.total_ipk / data.count) * 100) / 100 })) .sort((a, b) => { - // Sort by tahun_angkatan ASC + // Urutkan berdasarkan tahun_angkatan ASC return a.tahun_angkatan - b.tahun_angkatan; }); diff --git a/app/api/mahasiswa/ipk-prestasi/route.ts b/app/api/mahasiswa/ipk-prestasi/route.ts index 2941546..4fc9611 100644 --- a/app/api/mahasiswa/ipk-prestasi/route.ts +++ b/app/api/mahasiswa/ipk-prestasi/route.ts @@ -25,7 +25,7 @@ export async function GET(request: Request) { ); } - // Group and calculate statistics in JavaScript + // Kelompokkan dan hitung statistik di JavaScript const groupedData = data.reduce((acc: any[], row: any) => { const tahunAngkatan = row.tahun_angkatan; const ipk = row.ipk; @@ -50,14 +50,14 @@ export async function GET(request: Request) { return acc; }, []); - // Calculate average IPK and format the results + // Hitung rata-rata IPK dan format hasil const result = groupedData.map((group: any) => ({ tahun_angkatan: group.tahun_angkatan, total_mahasiswa_prestasi: group.total_mahasiswa_prestasi, rata_rata_ipk: Math.round((group.total_ipk / group.total_mahasiswa_prestasi) * 100) / 100 })); - // Sort by tahun_angkatan ascending + // Urutkan berdasarkan tahun_angkatan ascending const sortedData = result.sort((a: any, b: any) => a.tahun_angkatan - b.tahun_angkatan); return NextResponse.json(sortedData); diff --git a/app/api/mahasiswa/ipk-status/route.ts b/app/api/mahasiswa/ipk-status/route.ts index 3c90b5e..f0a7bcd 100644 --- a/app/api/mahasiswa/ipk-status/route.ts +++ b/app/api/mahasiswa/ipk-status/route.ts @@ -42,7 +42,7 @@ export async function GET(request: Request) { ); } - // Group by tahun_angkatan and status_kuliah + // Kelompokkan berdasarkan tahun_angkatan dan status_kuliah const groupedData = data.reduce((acc, item: any) => { const tahun_angkatan = item.tahun_angkatan; const status_kuliah = item.status_kuliah; @@ -64,7 +64,7 @@ export async function GET(request: Request) { return acc; }, {} as Record); - // Convert to final format and calculate average IPK + // Konversi ke format akhir dan hitung rata-rata IPK const results: IpkStatus[] = Object.values(groupedData) .map(item => ({ tahun_angkatan: item.tahun_angkatan, @@ -73,7 +73,7 @@ export async function GET(request: Request) { rata_rata_ipk: Math.round((item.total_ipk / item.total_mahasiswa) * 100) / 100 })) .sort((a, b) => { - // Sort by tahun_angkatan DESC, status_kuliah ASC + // Urutkan berdasarkan tahun_angkatan DESC, status_kuliah ASC if (a.tahun_angkatan !== b.tahun_angkatan) { return b.tahun_angkatan - a.tahun_angkatan; } diff --git a/app/api/mahasiswa/ipk/route.ts b/app/api/mahasiswa/ipk/route.ts index 91a3852..5e25b81 100644 --- a/app/api/mahasiswa/ipk/route.ts +++ b/app/api/mahasiswa/ipk/route.ts @@ -28,7 +28,7 @@ export async function GET() { ); } - // Group by tahun_angkatan and calculate average IPK + // Kelompokkan berdasarkan tahun_angkatan dan hitung rata-rata IPK const groupedData = data.reduce((acc, item) => { const tahun = item.tahun_angkatan; if (!acc[tahun]) { @@ -39,7 +39,7 @@ export async function GET() { return acc; }, {} as Record); - // Convert to final format + // Konversi ke format akhir const results: IPKData[] = Object.entries(groupedData).map(([tahun, data]) => ({ tahun_angkatan: parseInt(tahun), rata_rata_ipk: Math.round((data.sum / data.count) * 100) / 100 diff --git a/app/api/mahasiswa/jenis-beasiswa/route.ts b/app/api/mahasiswa/jenis-beasiswa/route.ts index fb2cf45..3d13a2b 100644 --- a/app/api/mahasiswa/jenis-beasiswa/route.ts +++ b/app/api/mahasiswa/jenis-beasiswa/route.ts @@ -17,7 +17,7 @@ export async function GET() { ); } - // Get unique jenis_beasiswa values + // Ambil nilai jenis_beasiswa yang unik const uniqueBeasiswa = [...new Set(data.map(item => item.jenis_beasiswa))]; return NextResponse.json(uniqueBeasiswa); diff --git a/app/api/mahasiswa/jenis-pendaftaran-beasiswa/route.ts b/app/api/mahasiswa/jenis-pendaftaran-beasiswa/route.ts index d5e5b7b..903360f 100644 --- a/app/api/mahasiswa/jenis-pendaftaran-beasiswa/route.ts +++ b/app/api/mahasiswa/jenis-pendaftaran-beasiswa/route.ts @@ -32,7 +32,7 @@ export async function GET(request: Request) { ); } - // Group and count the data in JavaScript + // Kelompokkan dan hitung data di JavaScript const groupedData = data.reduce((acc: any[], row: any) => { const tahunAngkatanValue = row.tahun_angkatan; const jenisPendaftaran = row.jenis_pendaftaran; @@ -58,7 +58,7 @@ export async function GET(request: Request) { return acc; }, []); - // Sort the results + // Urutkan hasil const sortedData = groupedData.sort((a: any, b: any) => { if (a.tahun_angkatan !== b.tahun_angkatan) { return b.tahun_angkatan - a.tahun_angkatan; diff --git a/app/api/mahasiswa/jenis-pendaftaran-lulus/route.ts b/app/api/mahasiswa/jenis-pendaftaran-lulus/route.ts index 080bc05..c138f3b 100644 --- a/app/api/mahasiswa/jenis-pendaftaran-lulus/route.ts +++ b/app/api/mahasiswa/jenis-pendaftaran-lulus/route.ts @@ -32,7 +32,7 @@ export async function GET(request: Request) { ); } - // Group by tahun_angkatan and jenis_pendaftaran + // Kelompokkan berdasarkan tahun_angkatan dan jenis_pendaftaran const groupedData = data.reduce((acc, item: any) => { const tahun_angkatan = item.tahun_angkatan; const jenis_pendaftaran = item.jenis_pendaftaran; @@ -41,7 +41,7 @@ export async function GET(request: Request) { return acc; }, {} as Record); - // Convert to final format and sort + // Konversi ke format akhir dan urutkan const results: JenisPendaftaranLulus[] = Object.entries(groupedData) .map(([key, jumlah_lulus_tepat_waktu]) => { const [tahun_angkatan, jenis_pendaftaran] = key.split('-'); @@ -52,7 +52,7 @@ export async function GET(request: Request) { }; }) .sort((a, b) => { - // Sort by tahun_angkatan DESC, jenis_pendaftaran ASC + // Urutkan berdasarkan tahun_angkatan DESC, jenis_pendaftaran ASC if (a.tahun_angkatan !== b.tahun_angkatan) { return b.tahun_angkatan - a.tahun_angkatan; } diff --git a/app/api/mahasiswa/jenis-pendaftaran-prestasi/route.ts b/app/api/mahasiswa/jenis-pendaftaran-prestasi/route.ts index cce40ae..cbe48d9 100644 --- a/app/api/mahasiswa/jenis-pendaftaran-prestasi/route.ts +++ b/app/api/mahasiswa/jenis-pendaftaran-prestasi/route.ts @@ -25,7 +25,7 @@ export async function GET(request: Request) { ); } - // Group and count the data in JavaScript + // Kelompokkan dan hitung data di JavaScript const groupedData = data.reduce((acc: any[], row: any) => { const tahunAngkatan = row.tahun_angkatan; const jenisPendaftaran = row.jenis_pendaftaran; @@ -51,7 +51,7 @@ export async function GET(request: Request) { return acc; }, []); - // Sort the results + // Urutkan hasil const sortedData = groupedData.sort((a: any, b: any) => { if (a.tahun_angkatan !== b.tahun_angkatan) { return b.tahun_angkatan - a.tahun_angkatan; diff --git a/app/api/mahasiswa/jenis-pendaftaran-status/route.ts b/app/api/mahasiswa/jenis-pendaftaran-status/route.ts index 99f9c95..dfa214a 100644 --- a/app/api/mahasiswa/jenis-pendaftaran-status/route.ts +++ b/app/api/mahasiswa/jenis-pendaftaran-status/route.ts @@ -41,7 +41,7 @@ export async function GET(request: Request) { ); } - // Group by jenis_pendaftaran, tahun_angkatan, status_kuliah + // Kelompokkan berdasarkan jenis_pendaftaran, tahun_angkatan, status_kuliah const groupedData = data.reduce((acc, item: any) => { const jenis_pendaftaran = item.jenis_pendaftaran; const tahun_angkatan = item.tahun_angkatan; @@ -51,7 +51,7 @@ export async function GET(request: Request) { return acc; }, {} as Record); - // Convert to final format and sort + // Konversi ke format akhir dan urutkan const results: JenisPendaftaranStatus[] = Object.entries(groupedData) .map(([key, total_mahasiswa]) => { const [jenis_pendaftaran, tahun_angkatan, status_kuliah] = key.split('-'); @@ -63,7 +63,7 @@ export async function GET(request: Request) { }; }) .sort((a, b) => { - // Sort by tahun_angkatan DESC, jenis_pendaftaran ASC, status_kuliah ASC + // Urutkan berdasarkan tahun_angkatan DESC, jenis_pendaftaran ASC, status_kuliah ASC if (a.tahun_angkatan !== b.tahun_angkatan) { return b.tahun_angkatan - a.tahun_angkatan; } diff --git a/app/api/mahasiswa/jenis-pendaftaran/route.ts b/app/api/mahasiswa/jenis-pendaftaran/route.ts index 3ee6dc4..6d7dfa1 100644 --- a/app/api/mahasiswa/jenis-pendaftaran/route.ts +++ b/app/api/mahasiswa/jenis-pendaftaran/route.ts @@ -37,14 +37,14 @@ export async function GET(request: Request) { ); } - // Group by tahun_angkatan and jenis_pendaftaran + // Kelompokkan berdasarkan tahun_angkatan dan jenis_pendaftaran const groupedData = data.reduce((acc, item) => { const key = `${item.tahun_angkatan}-${item.jenis_pendaftaran}`; acc[key] = (acc[key] || 0) + 1; return acc; }, {} as Record); - // Convert to final format + // Konversi ke format akhir const results: JenisPendaftaran[] = Object.entries(groupedData).map(([key, jumlah]) => { const [tahun_angkatan, jenis_pendaftaran] = key.split('-'); return { @@ -53,7 +53,7 @@ export async function GET(request: Request) { jumlah }; }).sort((a, b) => { - // Sort by tahun_angkatan DESC, then by jenis_pendaftaran + // Urutkan berdasarkan tahun_angkatan DESC, kemudian jenis_pendaftaran if (a.tahun_angkatan !== b.tahun_angkatan) { return b.tahun_angkatan - a.tahun_angkatan; } diff --git a/app/api/mahasiswa/jenis-prestasi/route.ts b/app/api/mahasiswa/jenis-prestasi/route.ts index b0744ff..caac67d 100644 --- a/app/api/mahasiswa/jenis-prestasi/route.ts +++ b/app/api/mahasiswa/jenis-prestasi/route.ts @@ -17,7 +17,7 @@ export async function GET() { ); } - // Get unique jenis_prestasi values + // Ambil nilai jenis_prestasi yang unik const uniquePrestasi = [...new Set(data.map(item => item.jenis_prestasi))]; return NextResponse.json(uniquePrestasi); diff --git a/app/api/mahasiswa/kelompok-keahlian-status/route.ts b/app/api/mahasiswa/kelompok-keahlian-status/route.ts index e37f988..7621175 100644 --- a/app/api/mahasiswa/kelompok-keahlian-status/route.ts +++ b/app/api/mahasiswa/kelompok-keahlian-status/route.ts @@ -41,7 +41,7 @@ export async function GET(request: Request) { ); } - // Group by tahun_angkatan, status_kuliah, nama_kelompok + // Kelompokkan berdasarkan tahun_angkatan, status_kuliah, nama_kelompok const groupedData = data.reduce((acc, item: any) => { const tahun_angkatan = item.tahun_angkatan; const status_kuliah = item.status_kuliah; @@ -51,7 +51,7 @@ export async function GET(request: Request) { return acc; }, {} as Record); - // Convert to final format and sort + // Konversi ke format akhir dan urutkan const results: KelompokKeahlianStatus[] = Object.entries(groupedData) .map(([key, jumlah_mahasiswa]) => { const [tahun_angkatan, status_kuliah, nama_kelompok] = key.split('-'); @@ -63,7 +63,7 @@ export async function GET(request: Request) { }; }) .sort((a, b) => { - // Sort by tahun_angkatan ASC, nama_kelompok ASC + // Urutkan berdasarkan tahun_angkatan ASC, nama_kelompok ASC if (a.tahun_angkatan !== b.tahun_angkatan) { return a.tahun_angkatan - b.tahun_angkatan; } diff --git a/app/api/mahasiswa/kk-dashboard-tepat/route.ts b/app/api/mahasiswa/kk-dashboard-tepat/route.ts index 0edc8df..ad6151a 100644 --- a/app/api/mahasiswa/kk-dashboard-tepat/route.ts +++ b/app/api/mahasiswa/kk-dashboard-tepat/route.ts @@ -8,7 +8,7 @@ interface KelompokKeahlianLulusTepat { export async function GET(request: Request) { try { - // Get all lulus students with their kelompok keahlian + // Ambil semua mahasiswa lulus dengan kelompok keahlian mereka const { data, error } = await supabase .from('mahasiswa') .select(` @@ -36,7 +36,7 @@ export async function GET(request: Request) { ); } - // Process data to calculate percentages + // Proses data untuk menghitung persentase const groupedData = data.reduce((acc, item: any) => { const nama_kelompok = item.kelompok_keahlian?.nama_kelompok; if (!nama_kelompok) return acc; @@ -50,7 +50,7 @@ export async function GET(request: Request) { acc[nama_kelompok].total_lulus += 1; - // Check if lulus tepat waktu (semester <= 8) + // Cek apakah lulus tepat waktu (semester <= 8) if (item.semester <= 8) { acc[nama_kelompok].lulus_tepat += 1; } @@ -58,7 +58,7 @@ export async function GET(request: Request) { return acc; }, {} as Record); - // Convert to final format (without percentage) and sort by count DESC then name ASC + // Konversi ke format akhir (tanpa persentase) dan urutkan berdasarkan jumlah DESC kemudian nama ASC const results: KelompokKeahlianLulusTepat[] = Object.entries(groupedData) .map(([nama_kelompok, counts]) => ({ nama_kelompok, diff --git a/app/api/mahasiswa/kk-dashboard/route.ts b/app/api/mahasiswa/kk-dashboard/route.ts index 9b87761..cf08c6e 100644 --- a/app/api/mahasiswa/kk-dashboard/route.ts +++ b/app/api/mahasiswa/kk-dashboard/route.ts @@ -38,7 +38,7 @@ export async function GET(request: Request) { ); } - // Group by tahun_angkatan, nama_kelompok + // Kelompokkan berdasarkan tahun_angkatan, nama_kelompok const groupedData = data.reduce((acc, item: any) => { const tahun_angkatan = item.tahun_angkatan; const nama_kelompok = item.kelompok_keahlian?.nama_kelompok; @@ -47,7 +47,7 @@ export async function GET(request: Request) { return acc; }, {} as Record); - // Convert to final format and sort + // Konversi ke format akhir dan urutkan const results: KelompokKeahlianStatus[] = Object.entries(groupedData) .map(([key, jumlah_mahasiswa]) => { const [tahun_angkatan, nama_kelompok] = key.split('-'); @@ -58,7 +58,7 @@ export async function GET(request: Request) { }; }) .sort((a, b) => { - // Sort by tahun_angkatan ASC, nama_kelompok ASC + // Urutkan berdasarkan tahun_angkatan ASC, nama_kelompok ASC if (a.tahun_angkatan !== b.tahun_angkatan) { return a.tahun_angkatan - b.tahun_angkatan; } diff --git a/app/api/mahasiswa/lulus-tepat-waktu/route.ts b/app/api/mahasiswa/lulus-tepat-waktu/route.ts index e86d91d..ae08034 100644 --- a/app/api/mahasiswa/lulus-tepat-waktu/route.ts +++ b/app/api/mahasiswa/lulus-tepat-waktu/route.ts @@ -32,7 +32,7 @@ export async function GET(request: Request) { ); } - // Group by tahun_angkatan and jk + // Kelompokkan berdasarkan tahun_angkatan dan jk const groupedData = data.reduce((acc, item: any) => { const tahun_angkatan = item.tahun_angkatan; const jk = item.jk; @@ -41,7 +41,7 @@ export async function GET(request: Request) { return acc; }, {} as Record); - // Convert to final format and sort + // Konversi ke format akhir dan urutkan const results: LulusTepatWaktu[] = Object.entries(groupedData) .map(([key, jumlah_lulus_tepat_waktu]) => { const [tahun_angkatan, jk] = key.split('-'); @@ -52,7 +52,7 @@ export async function GET(request: Request) { }; }) .sort((a, b) => { - // Sort by tahun_angkatan DESC, jk ASC + // Urutkan berdasarkan tahun_angkatan DESC, jk ASC if (a.tahun_angkatan !== b.tahun_angkatan) { return b.tahun_angkatan - a.tahun_angkatan; } diff --git a/app/api/mahasiswa/masa-studi-aktif/route.ts b/app/api/mahasiswa/masa-studi-aktif/route.ts index fc60060..d8088f2 100644 --- a/app/api/mahasiswa/masa-studi-aktif/route.ts +++ b/app/api/mahasiswa/masa-studi-aktif/route.ts @@ -39,7 +39,7 @@ export async function GET(req: Request) { ); } - // Group by tahun_angkatan, separate active and graduated students + // Kelompokkan berdasarkan tahun_angkatan, pisahkan mahasiswa aktif dan lulus const groupedData = data.reduce((acc, item) => { const tahun = item.tahun_angkatan; if (!acc[tahun]) { @@ -65,7 +65,7 @@ export async function GET(req: Request) { lulus: { sum: number; count: number }; }>); - // Convert to final format + // Konversi ke format akhir const results: MasaStudiAktifData[] = Object.values(groupedData).map((data) => ({ tahun_angkatan: data.tahun_angkatan, rata_rata_masa_studi_aktif_tahun: data.aktif.count > 0 @@ -76,7 +76,7 @@ export async function GET(req: Request) { : 0, })); - // Sort by tahun_angkatan + // Urutkan berdasarkan tahun_angkatan results.sort((a, b) => a.tahun_angkatan - b.tahun_angkatan); return NextResponse.json(results, { diff --git a/app/api/mahasiswa/masa-studi-status/route.ts b/app/api/mahasiswa/masa-studi-status/route.ts index 6f9ddd8..5c6ba37 100644 --- a/app/api/mahasiswa/masa-studi-status/route.ts +++ b/app/api/mahasiswa/masa-studi-status/route.ts @@ -42,7 +42,7 @@ export async function GET(req: Request) { ); } - // Group by tahun_angkatan and status_kuliah, calculate average semester/2 + // Kelompokkan berdasarkan tahun_angkatan dan status_kuliah, hitung rata-rata semester/2 const groupedData = data.reduce((acc, item) => { const tahun = item.tahun_angkatan; const status = item.status_kuliah; @@ -55,14 +55,14 @@ export async function GET(req: Request) { return acc; }, {} as Record); - // Convert to final format + // Konversi ke format akhir const results: MasaStudiData[] = Object.values(groupedData).map((data) => ({ tahun_angkatan: data.tahun_angkatan, status_kuliah: data.status_kuliah, rata_rata_masa_studi_tahun: Math.round(((data.sum / data.count) / 2) * 10) / 10, })); - // Sort by tahun_angkatan, status_kuliah + // Urutkan berdasarkan tahun_angkatan, status_kuliah results.sort((a, b) => { if (a.tahun_angkatan !== b.tahun_angkatan) { return a.tahun_angkatan - b.tahun_angkatan; diff --git a/app/api/mahasiswa/nama-beasiswa-dashboard/route.ts b/app/api/mahasiswa/nama-beasiswa-dashboard/route.ts index 13a8860..63b2263 100644 --- a/app/api/mahasiswa/nama-beasiswa-dashboard/route.ts +++ b/app/api/mahasiswa/nama-beasiswa-dashboard/route.ts @@ -30,7 +30,7 @@ export async function GET(request: Request) { ); } - // Group and count the data in JavaScript + // Kelompokkan dan hitung data di JavaScript const groupedData = data.reduce((acc: any[], row: any) => { const tahunAngkatanValue = row.mahasiswa?.tahun_angkatan; const namaBeasiswa = row.nama_beasiswa; @@ -58,7 +58,7 @@ export async function GET(request: Request) { return acc; }, []); - // Sort the results by tahun_angkatan ascending (as expected by component) + // Urutkan hasil berdasarkan tahun_angkatan ascending (sesuai yang diharapkan komponen) const sortedData = groupedData.sort((a: any, b: any) => { if (a.tahun_angkatan !== b.tahun_angkatan) { return a.tahun_angkatan - b.tahun_angkatan; diff --git a/app/api/mahasiswa/nama-beasiswa/route.ts b/app/api/mahasiswa/nama-beasiswa/route.ts index 5a0b686..adfadff 100644 --- a/app/api/mahasiswa/nama-beasiswa/route.ts +++ b/app/api/mahasiswa/nama-beasiswa/route.ts @@ -32,7 +32,7 @@ export async function GET(request: Request) { ); } - // Group and count the data in JavaScript + // Kelompokkan dan hitung data di JavaScript const groupedData = data.reduce((acc: any[], row: any) => { const tahunAngkatanValue = row.mahasiswa?.tahun_angkatan; const namaBeasiswa = row.nama_beasiswa; @@ -60,7 +60,7 @@ export async function GET(request: Request) { return acc; }, []); - // Sort the results by tahun_angkatan ascending (as expected by component) + // Urutkan hasil berdasarkan tahun_angkatan ascending (sesuai yang diharapkan komponen) const sortedData = groupedData.sort((a: any, b: any) => { if (a.tahun_angkatan !== b.tahun_angkatan) { return a.tahun_angkatan - b.tahun_angkatan; diff --git a/app/api/mahasiswa/profile/route.ts b/app/api/mahasiswa/profile/route.ts index 7436c9f..a608a4c 100644 --- a/app/api/mahasiswa/profile/route.ts +++ b/app/api/mahasiswa/profile/route.ts @@ -43,7 +43,7 @@ interface MahasiswaProfile { export async function GET(request: Request) { try { - // Get token from cookies + // Ambil token dari cookies const cookieStore = await cookies(); const token = cookieStore.get('token')?.value; @@ -54,7 +54,7 @@ export async function GET(request: Request) { ); } - // Verify JWT token + // Verifikasi JWT token const { payload } = await jwtVerify( token, new TextEncoder().encode(process.env.JWT_SECRET || 'your-secret-key') @@ -62,7 +62,7 @@ export async function GET(request: Request) { const nim = payload.nim as string; - // Get mahasiswa data + // Ambil data mahasiswa const { data: mahasiswaData, error: mahasiswaError } = await supabase .from('mahasiswa') .select(` @@ -86,14 +86,14 @@ export async function GET(request: Request) { ); } - // Get status_mahasiswa data + // Ambil data status_mahasiswa const { data: statusData, error: statusError } = await supabase .from('status_mahasiswa') .select('status_kuliah, semester') .eq('nim', nim) .single(); - // Get prestasi_mahasiswa data + // Ambil data prestasi_mahasiswa const { data: prestasiData, error: prestasiError } = await supabase .from('prestasi_mahasiswa') .select(` @@ -105,7 +105,7 @@ export async function GET(request: Request) { `) .eq('nim', nim); - // Get beasiswa_mahasiswa data + // Ambil data beasiswa_mahasiswa const { data: beasiswaData, error: beasiswaError } = await supabase .from('beasiswa_mahasiswa') .select(` @@ -116,7 +116,7 @@ export async function GET(request: Request) { `) .eq('nim', nim); - // Transform the data to match the expected interface + // Transformasi data sesuai interface yang diharapkan const profile: MahasiswaProfile = { // Data Mahasiswa nama: mahasiswaData.nama, diff --git a/app/api/mahasiswa/provinsi-mahasiswa/route.ts b/app/api/mahasiswa/provinsi-mahasiswa/route.ts index 9293bd0..dcc867f 100644 --- a/app/api/mahasiswa/provinsi-mahasiswa/route.ts +++ b/app/api/mahasiswa/provinsi-mahasiswa/route.ts @@ -3,7 +3,7 @@ import supabase from '@/lib/db'; export async function GET(request: Request) { try { - // Get all mahasiswa data and process in JavaScript + // Ambil semua data mahasiswa dan proses di JavaScript const { data: mahasiswaData, error } = await supabase .from('mahasiswa') .select('provinsi'); @@ -16,7 +16,7 @@ export async function GET(request: Request) { ); } - // Process the data in JavaScript + // Proses data di JavaScript let kalimantanBarat = 0; let luarKalimantanBarat = 0; @@ -30,7 +30,7 @@ export async function GET(request: Request) { } }); - // Transform the data to match the expected format + // Transformasi data sesuai format yang diharapkan const result = [ { provinsi: 'Kalimantan Barat', diff --git a/app/api/mahasiswa/statistik/route.ts b/app/api/mahasiswa/statistik/route.ts index fc8a13d..4e4dba9 100644 --- a/app/api/mahasiswa/statistik/route.ts +++ b/app/api/mahasiswa/statistik/route.ts @@ -23,7 +23,7 @@ export async function OPTIONS() { export async function GET() { try { - // Get all mahasiswa data + // Ambil semua data mahasiswa const { data, error } = await supabase .from('mahasiswa') .select('tahun_angkatan, jk'); @@ -43,7 +43,7 @@ export async function GET() { ); } - // Group by tahun_angkatan and calculate statistics + // Kelompokkan berdasarkan tahun_angkatan dan hitung statistik const groupedData = data.reduce((acc, item) => { const tahun = item.tahun_angkatan; if (!acc[tahun]) { @@ -65,7 +65,7 @@ export async function GET() { return acc; }, {} as Record); - // Convert to array and sort by tahun_angkatan + // Konversi ke array dan urutkan berdasarkan tahun_angkatan const results: MahasiswaStatistik[] = Object.values(groupedData) .sort((a, b) => a.tahun_angkatan - b.tahun_angkatan); diff --git a/app/api/mahasiswa/status-kuliah/route.ts b/app/api/mahasiswa/status-kuliah/route.ts index 100e3d5..1d8efdf 100644 --- a/app/api/mahasiswa/status-kuliah/route.ts +++ b/app/api/mahasiswa/status-kuliah/route.ts @@ -38,7 +38,7 @@ export async function GET(request: Request) { ); } - // Group and count the data in JavaScript + // Kelompokkan dan hitung data di JavaScript const groupedData = data.reduce((acc: any[], row: any) => { const tahunAngkatanValue = row.tahun_angkatan; const statusKuliah = row.status_kuliah; @@ -64,7 +64,7 @@ export async function GET(request: Request) { return acc; }, []); - // Sort the results + // Urutkan hasil const sortedData = groupedData.sort((a: any, b: any) => { if (a.tahun_angkatan !== b.tahun_angkatan) { return a.tahun_angkatan - b.tahun_angkatan; diff --git a/app/api/mahasiswa/status-mahasiswa/route.ts b/app/api/mahasiswa/status-mahasiswa/route.ts index 61a9720..356e998 100644 --- a/app/api/mahasiswa/status-mahasiswa/route.ts +++ b/app/api/mahasiswa/status-mahasiswa/route.ts @@ -39,7 +39,7 @@ export async function GET(request: Request) { ); } - // Group by tahun_angkatan and jk + // Kelompokkan berdasarkan tahun_angkatan dan jk const groupedData = data.reduce((acc, item: any) => { const tahun_angkatan = item.tahun_angkatan; const jk = item.jk; @@ -48,7 +48,7 @@ export async function GET(request: Request) { return acc; }, {} as Record); - // Convert to final format + // Konversi ke format akhir const results: StatusMahasiswa[] = Object.entries(groupedData).map(([key, total_mahasiswa]) => { const [tahun_angkatan, jk] = key.split('-'); return { @@ -57,7 +57,7 @@ export async function GET(request: Request) { total_mahasiswa }; }).sort((a, b) => { - // Sort by tahun_angkatan DESC, then by jk + // Urutkan berdasarkan tahun_angkatan DESC, kemudian jk if (a.tahun_angkatan !== b.tahun_angkatan) { return b.tahun_angkatan - a.tahun_angkatan; } diff --git a/app/api/mahasiswa/status/route.ts b/app/api/mahasiswa/status/route.ts index 1d6cd21..aa678fc 100644 --- a/app/api/mahasiswa/status/route.ts +++ b/app/api/mahasiswa/status/route.ts @@ -22,7 +22,7 @@ export async function GET() { ); } - // Group by tahun_angkatan and status_kuliah + // Kelompokkan berdasarkan tahun_angkatan dan status_kuliah const groupedData = data.reduce((acc, item: any) => { const tahun_angkatan = item.tahun_angkatan; const status_kuliah = item.status_kuliah; @@ -31,7 +31,7 @@ export async function GET() { return acc; }, {} as Record); - // Convert to final format + // Konversi ke format akhir const results: StatusData[] = Object.entries(groupedData).map(([key, jumlah]) => { const [tahun_angkatan, status_kuliah] = key.split('-'); return { diff --git a/app/api/mahasiswa/tahun-angkatan/route.ts b/app/api/mahasiswa/tahun-angkatan/route.ts index a88cd79..fb54aa2 100644 --- a/app/api/mahasiswa/tahun-angkatan/route.ts +++ b/app/api/mahasiswa/tahun-angkatan/route.ts @@ -25,10 +25,10 @@ export async function GET() { ); } - // Get unique tahun_angkatan values and limit to 7 most recent + // Ambil nilai tahun_angkatan unik dan batasi 7 tahun terbaru const uniqueYears = [...new Set(data.map(item => item.tahun_angkatan))] - .sort((a, b) => b - a) // Sort descending - .slice(0, 7); // Take only 7 most recent years + .sort((a, b) => b - a) // Urutkan descending + .slice(0, 7); // Ambil hanya 7 tahun terbaru return NextResponse.json(uniqueYears, { headers: { diff --git a/app/api/mahasiswa/tingkat-prestasi-dashboard/route.ts b/app/api/mahasiswa/tingkat-prestasi-dashboard/route.ts index 270bcd1..cdce214 100644 --- a/app/api/mahasiswa/tingkat-prestasi-dashboard/route.ts +++ b/app/api/mahasiswa/tingkat-prestasi-dashboard/route.ts @@ -6,7 +6,7 @@ export async function GET(request: Request) { const { searchParams } = new URL(request.url); const tahunAngkatan = searchParams.get('tahunAngkatan'); - // Build query based on parameters + // Bangun query berdasarkan parameter let query = supabase .from('mahasiswa') .select(` @@ -17,7 +17,7 @@ export async function GET(request: Request) { ) `); - // Add tahun angkatan filter if provided and not 'all' + // Tambahkan filter tahun angkatan jika diberikan dan bukan 'all' if (tahunAngkatan && tahunAngkatan !== 'null' && tahunAngkatan !== 'undefined' && tahunAngkatan !== 'all') { query = query.eq('tahun_angkatan', parseInt(tahunAngkatan)); } @@ -32,18 +32,18 @@ export async function GET(request: Request) { ); } - // Group and count the data in JavaScript + // Kelompokkan dan hitung data di JavaScript const groupedData = data.reduce((acc: any[], row: any) => { const tahunAngkatan = row.tahun_angkatan; - // Handle array of prestasi_mahasiswa + // Tangani array prestasi_mahasiswa const prestasiArray = Array.isArray(row.prestasi_mahasiswa) ? row.prestasi_mahasiswa : [row.prestasi_mahasiswa]; if (!tahunAngkatan) { return acc; } - // Process each prestasi in the array + // Proses setiap prestasi dalam array prestasiArray.forEach((prestasi: any) => { if (!prestasi || !prestasi.tingkat_prestasi) { return; @@ -72,7 +72,7 @@ export async function GET(request: Request) { return acc; }, []); - // Sort the results + // Urutkan hasil const sortedData = groupedData.sort((a: any, b: any) => { if (a.tahun_angkatan !== b.tahun_angkatan) { return b.tahun_angkatan - a.tahun_angkatan; diff --git a/app/api/mahasiswa/tingkat-prestasi/route.ts b/app/api/mahasiswa/tingkat-prestasi/route.ts index e4feb7c..7bd6420 100644 --- a/app/api/mahasiswa/tingkat-prestasi/route.ts +++ b/app/api/mahasiswa/tingkat-prestasi/route.ts @@ -7,9 +7,9 @@ export async function GET(request: Request) { const tahunAngkatan = searchParams.get('tahunAngkatan'); const jenisPrestasi = searchParams.get('jenisPrestasi'); - // Validate jenisPrestasi parameter (allow null) + // Validasi parameter jenisPrestasi (izinkan null) if (jenisPrestasi && jenisPrestasi !== 'null' && jenisPrestasi !== 'undefined') { - // Validate against valid enum values only if jenisPrestasi is provided + // Validasi terhadap nilai enum yang valid hanya jika jenisPrestasi diberikan const validJenisPrestasi = ['Akademik', 'Non-Akademik']; if (!validJenisPrestasi.includes(jenisPrestasi)) { return NextResponse.json( @@ -19,7 +19,7 @@ export async function GET(request: Request) { } } - // Build query based on parameters + // Bangun query berdasarkan parameter let query = supabase .from('mahasiswa') .select(` @@ -30,12 +30,12 @@ export async function GET(request: Request) { ) `); - // Add tahun angkatan filter if provided + // Tambahkan filter tahun angkatan jika diberikan if (tahunAngkatan && tahunAngkatan !== 'null' && tahunAngkatan !== 'undefined') { query = query.eq('tahun_angkatan', parseInt(tahunAngkatan)); } - // Add jenis prestasi filter if provided + // Tambahkan filter jenis prestasi jika diberikan if (jenisPrestasi && jenisPrestasi !== 'null' && jenisPrestasi !== 'undefined') { query = query.eq('prestasi_mahasiswa.jenis_prestasi', jenisPrestasi); } @@ -50,18 +50,18 @@ export async function GET(request: Request) { ); } - // Group and count the data in JavaScript + // Kelompokkan dan hitung data di JavaScript const groupedData = data.reduce((acc: any[], row: any) => { const tahunAngkatan = row.tahun_angkatan; - // Handle array of prestasi_mahasiswa + // Tangani array prestasi_mahasiswa const prestasiArray = Array.isArray(row.prestasi_mahasiswa) ? row.prestasi_mahasiswa : [row.prestasi_mahasiswa]; if (!tahunAngkatan) { return acc; } - // Process each prestasi in the array + // Proses setiap prestasi dalam array prestasiArray.forEach((prestasi: any) => { if (!prestasi || !prestasi.tingkat_prestasi) { return; @@ -90,7 +90,7 @@ export async function GET(request: Request) { return acc; }, []); - // Sort the results + // Urutkan hasil const sortedData = groupedData.sort((a: any, b: any) => { if (a.tahun_angkatan !== b.tahun_angkatan) { return b.tahun_angkatan - a.tahun_angkatan; diff --git a/app/api/mahasiswa/total-beasiswa/route.ts b/app/api/mahasiswa/total-beasiswa/route.ts index e1faf0b..3cbfd4a 100644 --- a/app/api/mahasiswa/total-beasiswa/route.ts +++ b/app/api/mahasiswa/total-beasiswa/route.ts @@ -32,7 +32,7 @@ export async function GET(request: Request) { ); } - // Group by tahun_angkatan and jk + // Kelompokkan berdasarkan tahun_angkatan dan jk const groupedData = data.reduce((acc, item: any) => { const tahun_angkatan = item.mahasiswa.tahun_angkatan; const jk = item.mahasiswa.jk; @@ -41,7 +41,7 @@ export async function GET(request: Request) { return acc; }, {} as Record); - // Convert to final format + // Konversi ke format akhir const results: BeasiswaData[] = Object.entries(groupedData).map(([key, jumlah_mahasiswa_beasiswa]) => { const [tahun_angkatan, jk] = key.split('-'); return { @@ -50,7 +50,7 @@ export async function GET(request: Request) { jumlah_mahasiswa_beasiswa }; }).sort((a, b) => { - // Sort by tahun_angkatan DESC, then by jk + // Urutkan berdasarkan tahun_angkatan DESC, kemudian jk if (a.tahun_angkatan !== b.tahun_angkatan) { return b.tahun_angkatan - a.tahun_angkatan; } diff --git a/app/api/mahasiswa/total-prestasi/route.ts b/app/api/mahasiswa/total-prestasi/route.ts index c135230..8c99be0 100644 --- a/app/api/mahasiswa/total-prestasi/route.ts +++ b/app/api/mahasiswa/total-prestasi/route.ts @@ -31,7 +31,7 @@ export async function GET(request: Request) { ); } - // Group by tahun_angkatan and jk + // Kelompokkan berdasarkan tahun_angkatan dan jk const groupedData = data.reduce((acc: any[], item: any) => { const tahunAngkatan = item.tahun_angkatan; const jk = item.jk; @@ -55,7 +55,7 @@ export async function GET(request: Request) { return acc; }, []); - // Sort by tahun_angkatan DESC, then by jk + // Urutkan berdasarkan tahun_angkatan DESC, kemudian jk const sortedData = groupedData.sort((a: any, b: any) => { if (a.tahun_angkatan !== b.tahun_angkatan) { return b.tahun_angkatan - a.tahun_angkatan; diff --git a/app/api/mahasiswa/total/route.ts b/app/api/mahasiswa/total/route.ts index c2a525a..0d68841 100644 --- a/app/api/mahasiswa/total/route.ts +++ b/app/api/mahasiswa/total/route.ts @@ -31,55 +31,55 @@ export async function OPTIONS() { export async function GET() { try { - // jumlah mahasiswa + // Jumlah mahasiswa const { count: totalMahasiswa } = await supabase .from('mahasiswa') .select('*', { count: 'exact', head: true }); - // Get mahasiswa aktif + // Ambil mahasiswa aktif const { count: mahasiswaAktif } = await supabase .from('mahasiswa') .select('*', { count: 'exact', head: true }) .eq('status_kuliah', 'Aktif'); - // Get total lulus + // Ambil total lulus const { count: totalLulus } = await supabase .from('mahasiswa') .select('*', { count: 'exact', head: true }) .eq('status_kuliah', 'Lulus'); - // Get pria lulus + // Ambil pria lulus const { count: priaLulus } = await supabase .from('mahasiswa') .select('*', { count: 'exact', head: true }) .eq('status_kuliah', 'Lulus') .eq('jk', 'Pria'); - // Get wanita lulus + // Ambil wanita lulus const { count: wanitaLulus } = await supabase .from('mahasiswa') .select('*', { count: 'exact', head: true }) .eq('status_kuliah', 'Lulus') .eq('jk', 'Wanita'); - // Get total berprestasi + // Ambil total berprestasi const { count: totalBerprestasi } = await supabase .from('prestasi_mahasiswa') .select('*', { count: 'exact', head: true }); - // Get prestasi akademik + // Ambil prestasi akademik const { count: prestasiAkademik } = await supabase .from('prestasi_mahasiswa') .select('*', { count: 'exact', head: true }) .eq('jenis_prestasi', 'Akademik'); - // Get prestasi non-akademik + // Ambil 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 + // Ambil total mahasiswa aktif + lulus const { count: totalMahasiswaAktifLulus } = await supabase .from('mahasiswa') .select('*', { count: 'exact', head: true }) diff --git a/components/charts/AsalDaerahBeasiswaChart.tsx b/components/charts/AsalDaerahBeasiswaChart.tsx index 6cc1c34..d9a27f7 100644 --- a/components/charts/AsalDaerahBeasiswaChart.tsx +++ b/components/charts/AsalDaerahBeasiswaChart.tsx @@ -6,7 +6,7 @@ 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 +// Import ApexCharts secara dinamis untuk menghindari masalah SSR const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface AsalDaerahBeasiswaData { @@ -48,13 +48,13 @@ export default function AsalDaerahBeasiswaChart({ selectedYear, selectedJenisBea const result = await response.json(); if (!Array.isArray(result)) { - throw new Error('Invalid data format received from server'); + throw new Error('Format data tidak valid diterima dari server'); } setData(result); } catch (err) { console.error('Error in fetchData:', err); - setError(err instanceof Error ? err.message : 'An error occurred while fetching data'); + setError(err instanceof Error ? err.message : 'Terjadi kesalahan saat mengambil data'); } finally { setLoading(false); } @@ -109,7 +109,7 @@ export default function AsalDaerahBeasiswaChart({ selectedYear, selectedJenisBea colors: [theme === 'dark' ? '#374151' : '#E5E7EB'], }, xaxis: { - categories: [...new Set(data.map(item => item.kabupaten))].sort(), + categories: [...new Set(data.map(item => item.kabupaten))].sort(), // Ambil kabupaten unik dan urutkan title: { text: 'Jumlah Mahasiswa', style: { @@ -166,7 +166,7 @@ export default function AsalDaerahBeasiswaChart({ selectedYear, selectedJenisBea const series = [{ name: 'Jumlah Mahasiswa', - data: [...new Set(data.map(item => item.kabupaten))].sort().map(kabupaten => { + data: [...new Set(data.map(item => item.kabupaten))].sort().map(kabupaten => { // Ambil kabupaten unik, urutkan, dan map ke jumlah mahasiswa const item = data.find(d => d.kabupaten === kabupaten); return item ? item.jumlah_mahasiswa : 0; }) diff --git a/components/charts/AsalDaerahChart.tsx b/components/charts/AsalDaerahChart.tsx index 14aff3d..d86caa5 100644 --- a/components/charts/AsalDaerahChart.tsx +++ b/components/charts/AsalDaerahChart.tsx @@ -9,7 +9,7 @@ import { Button } from "@/components/ui/button"; import { ExternalLink } from "lucide-react"; import Link from "next/link"; -// Dynamically import ApexCharts to avoid SSR issues +// Import ApexCharts secara dinamis untuk menghindari masalah SSR const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface AsalDaerahData { @@ -107,7 +107,7 @@ export default function AsalDaerahChart({ fill: { opacity: 1, }, - colors: ['#3B82F6'], // Blue color for bars + colors: ['#3B82F6'], // Warna biru untuk bar tooltip: { theme: theme === 'dark' ? 'dark' : 'light', y: { @@ -118,7 +118,7 @@ export default function AsalDaerahChart({ } }); - // Update theme when it changes + // Perbarui tema saat berubah useEffect(() => { setOptions(prev => ({ ...prev, @@ -193,12 +193,12 @@ export default function AsalDaerahChart({ const result = await response.json(); if (!Array.isArray(result)) { - throw new Error('Invalid data format received from server'); + throw new Error('Format data tidak valid diterima dari server'); } setData(result); - // Process data for chart + // Proses data untuk chart const kabupaten = result.map(item => item.kabupaten); const jumlah = result.map(item => item.jumlah); @@ -215,7 +215,7 @@ export default function AsalDaerahChart({ })); } catch (err) { console.error('Error in fetchData:', err); - setError(err instanceof Error ? err.message : 'An error occurred while fetching data'); + setError(err instanceof Error ? err.message : 'Terjadi kesalahan saat mengambil data'); } finally { setLoading(false); } @@ -264,11 +264,11 @@ export default function AsalDaerahChart({ ); } - // Calculate dynamic height based on number of kabupaten + // Hitung tinggi dinamis berdasarkan jumlah kabupaten const calculateHeight = () => { const minHeight = 100; - const barHeight = 15; // Height per bar in pixels - const padding = 50; // Extra space for title, legend, etc. + const barHeight = 15; // Tinggi per bar dalam piksel + const padding = 50; // Ruang ekstra untuk judul, legenda, dll const dynamicHeight = Math.max(minHeight, (data.length * barHeight) + padding); return `${dynamicHeight}px`; }; diff --git a/components/charts/AsalDaerahLulusChart.tsx b/components/charts/AsalDaerahLulusChart.tsx index 1938828..b7affe6 100644 --- a/components/charts/AsalDaerahLulusChart.tsx +++ b/components/charts/AsalDaerahLulusChart.tsx @@ -6,7 +6,7 @@ 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 +// Import ApexCharts secara dinamis untuk menghindari masalah SSR const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface AsalDaerahLulusChartProps { @@ -110,7 +110,7 @@ export default function AsalDaerahLulusChart({ selectedYear }: AsalDaerahLulusCh fill: { opacity: 1, }, - colors: ['#3B82F6'], // Blue color for bars + colors: ['#3B82F6'], // Warna biru untuk bar tooltip: { theme: theme === 'dark' ? 'dark' : 'light', y: { @@ -121,7 +121,7 @@ export default function AsalDaerahLulusChart({ selectedYear }: AsalDaerahLulusCh } }); - // Update theme when it changes + // Perbarui tema saat berubah useEffect(() => { const currentTheme = theme; setOptions(prev => ({ @@ -196,7 +196,7 @@ export default function AsalDaerahLulusChart({ selectedYear }: AsalDaerahLulusCh const data = await response.json(); setChartData(data); - // Process data for chart + // Proses data untuk chart const kabupaten = data.map((item: ChartData) => item.kabupaten); const jumlah = data.map((item: ChartData) => item.jumlah_lulus_tepat_waktu); @@ -212,7 +212,7 @@ export default function AsalDaerahLulusChart({ selectedYear }: AsalDaerahLulusCh }, })); } catch (err) { - setError(err instanceof Error ? err.message : 'An error occurred'); + setError(err instanceof Error ? err.message : 'Terjadi kesalahan'); console.error('Error fetching data:', err); } finally { setIsLoading(false); diff --git a/components/charts/AsalDaerahPerAngkatanChart.tsx b/components/charts/AsalDaerahPerAngkatanChart.tsx index 760eea6..2591571 100644 --- a/components/charts/AsalDaerahPerAngkatanChart.tsx +++ b/components/charts/AsalDaerahPerAngkatanChart.tsx @@ -6,7 +6,7 @@ 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 +// Import ApexCharts secara dinamis untuk menghindari masalah SSR const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface AsalDaerahData { @@ -126,7 +126,7 @@ export default function AsalDaerahPerAngkatanChart({ tahunAngkatan }: Props) { fill: { opacity: 1, }, - colors: ['#3B82F6'], // Blue color for bars + colors: ['#3B82F6'], // Warna biru untuk bar tooltip: { theme: theme === 'dark' ? 'dark' : 'light', y: { @@ -137,7 +137,7 @@ export default function AsalDaerahPerAngkatanChart({ tahunAngkatan }: Props) { } }); - // Update theme when it changes + // Perbarui tema saat berubah useEffect(() => { setOptions(prev => ({ ...prev, @@ -212,12 +212,12 @@ export default function AsalDaerahPerAngkatanChart({ tahunAngkatan }: Props) { const result = await response.json(); if (!Array.isArray(result)) { - throw new Error('Invalid data format received from server'); + throw new Error('Format data tidak valid diterima dari server'); } setData(result); - // Process data for chart + // Proses data untuk chart const kabupaten = result.map(item => item.kabupaten); const jumlah = result.map(item => item.jumlah); @@ -248,7 +248,7 @@ export default function AsalDaerahPerAngkatanChart({ tahunAngkatan }: Props) { })); } catch (err) { console.error('Error in fetchData:', err); - setError(err instanceof Error ? err.message : 'An error occurred while fetching data'); + setError(err instanceof Error ? err.message : 'Terjadi kesalahan saat mengambil data'); } finally { setLoading(false); } @@ -299,11 +299,11 @@ export default function AsalDaerahPerAngkatanChart({ tahunAngkatan }: Props) { ); } - // Calculate dynamic height based on number of kabupaten + // Hitung tinggi dinamis berdasarkan jumlah kabupaten const calculateHeight = () => { const minHeight = 100; - const barHeight = 15; // Height per bar in pixels - const padding = 50; // Extra space for title, legend, etc. + const barHeight = 15; // Tinggi per bar dalam piksel + const padding = 50; // Ruang ekstra untuk judul, legenda, dll const dynamicHeight = Math.max(minHeight, (data.length * barHeight) + padding); return `${dynamicHeight}px`; }; diff --git a/components/charts/AsalDaerahPrestasiChart.tsx b/components/charts/AsalDaerahPrestasiChart.tsx index 861b1de..9d14eca 100644 --- a/components/charts/AsalDaerahPrestasiChart.tsx +++ b/components/charts/AsalDaerahPrestasiChart.tsx @@ -6,7 +6,7 @@ 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 +// Import ApexCharts secara dinamis untuk menghindari masalah SSR const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface AsalDaerahPrestasiData { @@ -48,13 +48,13 @@ export default function AsalDaerahPrestasiChart({ selectedYear, selectedJenisPre const result = await response.json(); if (!Array.isArray(result)) { - throw new Error('Invalid data format received from server'); + throw new Error('Format data tidak valid diterima dari server'); } setData(result); } catch (err) { console.error('Error in fetchData:', err); - setError(err instanceof Error ? err.message : 'An error occurred while fetching data'); + setError(err instanceof Error ? err.message : 'Terjadi kesalahan saat mengambil data'); } finally { setLoading(false); } @@ -109,7 +109,7 @@ export default function AsalDaerahPrestasiChart({ selectedYear, selectedJenisPre colors: [theme === 'dark' ? '#374151' : '#E5E7EB'], }, xaxis: { - categories: [...new Set(data.map(item => item.kabupaten))].sort(), + categories: [...new Set(data.map(item => item.kabupaten))].sort(), // Ambil kabupaten unik dan urutkan title: { text: 'Jumlah Mahasiswa', style: { @@ -166,7 +166,7 @@ export default function AsalDaerahPrestasiChart({ selectedYear, selectedJenisPre const series = [{ name: 'Jumlah Mahasiswa', - data: [...new Set(data.map(item => item.kabupaten))].sort().map(kabupaten => { + data: [...new Set(data.map(item => item.kabupaten))].sort().map(kabupaten => { // Ambil kabupaten unik, urutkan, dan map ke jumlah mahasiswa prestasi const item = data.find(d => d.kabupaten === kabupaten); return item ? item.asal_daerah_mahasiswa_prestasi : 0; }) diff --git a/components/charts/AsalDaerahStatusChart.tsx b/components/charts/AsalDaerahStatusChart.tsx index ec41394..c9a6703 100644 --- a/components/charts/AsalDaerahStatusChart.tsx +++ b/components/charts/AsalDaerahStatusChart.tsx @@ -6,7 +6,7 @@ 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 +// Import ApexCharts secara dinamis untuk menghindari masalah SSR const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface AsalDaerahStatusData { @@ -44,7 +44,7 @@ export default function AsalDaerahStatusChart({ selectedYear, selectedStatus }: const result = await response.json(); console.log('Received data:', result); - // Sort data by kabupaten + // Urutkan data berdasarkan kabupaten const sortedData = result.sort((a: AsalDaerahStatusData, b: AsalDaerahStatusData) => a.kabupaten.localeCompare(b.kabupaten) ); @@ -52,7 +52,7 @@ export default function AsalDaerahStatusChart({ selectedYear, selectedStatus }: setData(sortedData); } catch (err) { console.error('Error in fetchData:', err); - setError(err instanceof Error ? err.message : 'An error occurred'); + setError(err instanceof Error ? err.message : 'Terjadi kesalahan'); } finally { setLoading(false); } @@ -61,12 +61,12 @@ export default function AsalDaerahStatusChart({ selectedYear, selectedStatus }: fetchData(); }, [selectedYear, selectedStatus]); - // Log data changes + // Log perubahan data useEffect(() => { console.log('Current data state:', data); }, [data]); - // Get unique kabupaten + // Ambil kabupaten unik const kabupaten = [...new Set(data.map(item => item.kabupaten))].sort(); console.log('Kabupaten:', kabupaten); @@ -164,7 +164,7 @@ export default function AsalDaerahStatusChart({ selectedYear, selectedStatus }: } }; - // Process data for series + // Proses data untuk series const processSeriesData = () => { const seriesData = kabupaten.map(kab => { const item = data.find(d => d.kabupaten === kab); diff --git a/components/charts/IPKBeasiswaChart.tsx b/components/charts/IPKBeasiswaChart.tsx index 478fe1d..0837f4b 100644 --- a/components/charts/IPKBeasiswaChart.tsx +++ b/components/charts/IPKBeasiswaChart.tsx @@ -6,7 +6,7 @@ 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 +// Import ApexCharts secara dinamis untuk menghindari masalah SSR const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface IPKBeasiswaData { @@ -161,7 +161,7 @@ export default function IPKBeasiswaChart({ selectedJenisBeasiswa }: Props) { } }); - // Update theme when it changes + // Perbarui tema saat berubah useEffect(() => { const currentTheme = theme; setOptions(prev => ({ @@ -250,12 +250,12 @@ export default function IPKBeasiswaChart({ selectedJenisBeasiswa }: Props) { const result = await response.json(); if (!Array.isArray(result)) { - throw new Error('Invalid data format received from server'); + throw new Error('Format data tidak valid diterima dari server'); } setData(result); - // Process data for chart + // Proses data untuk chart const tahunAngkatan = result.map(item => item.tahun_angkatan); const rataRataIPK = result.map(item => item.rata_rata_ipk); @@ -272,7 +272,7 @@ export default function IPKBeasiswaChart({ selectedJenisBeasiswa }: Props) { })); } catch (err) { console.error('Error in fetchData:', err); - setError(err instanceof Error ? err.message : 'An error occurred while fetching data'); + setError(err instanceof Error ? err.message : 'Terjadi kesalahan saat mengambil data'); } finally { setLoading(false); } diff --git a/components/charts/IPKChart.tsx b/components/charts/IPKChart.tsx index 3528620..95a5a27 100644 --- a/components/charts/IPKChart.tsx +++ b/components/charts/IPKChart.tsx @@ -9,7 +9,7 @@ import { Button } from "@/components/ui/button"; import { ExternalLink } from "lucide-react"; import Link from "next/link"; -// Dynamically import ApexCharts to avoid SSR issues +// Import ApexCharts secara dinamis untuk menghindari masalah SSR const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface IPKData { @@ -145,7 +145,7 @@ export default function IPKChart({ left: 0 } }, - colors: ['#3B82F6'], // Blue color for line + colors: ['#3B82F6'], // Warna biru untuk garis tooltip: { theme: theme === 'dark' ? 'dark' : 'light', y: { @@ -167,7 +167,7 @@ export default function IPKChart({ } }); - // Update theme when it changes + // Perbarui tema saat berubah useEffect(() => { const currentTheme = theme; setOptions(prev => ({ @@ -256,12 +256,12 @@ export default function IPKChart({ const result = await response.json(); if (!Array.isArray(result)) { - throw new Error('Invalid data format received from server'); + throw new Error('Format data tidak valid diterima dari server'); } setData(result); - // Process data for chart + // Proses data untuk chart const tahunAngkatan = result.map(item => item.tahun_angkatan); const rataRataIPK = result.map(item => item.rata_rata_ipk); @@ -278,7 +278,7 @@ export default function IPKChart({ })); } catch (err) { console.error('Error in fetchData:', err); - setError(err instanceof Error ? err.message : 'An error occurred while fetching data'); + setError(err instanceof Error ? err.message : 'Terjadi kesalahan saat mengambil data'); } finally { setLoading(false); } diff --git a/components/charts/IPKJenisKelaminChart.tsx b/components/charts/IPKJenisKelaminChart.tsx index e74b5bf..9f5915b 100644 --- a/components/charts/IPKJenisKelaminChart.tsx +++ b/components/charts/IPKJenisKelaminChart.tsx @@ -117,7 +117,7 @@ export default function IPKJenisKelaminChart({ tahunAngkatan }: Props) { } }); - // Update theme when it changes + // Perbarui tema saat berubah useEffect(() => { const currentTheme = theme; setOptions(prev => ({ @@ -202,7 +202,7 @@ export default function IPKJenisKelaminChart({ tahunAngkatan }: Props) { return; } - // Process data for chart + // Proses data untuk chart const labels = data.map((item: any) => { console.log('Processing item:', item); return item.jk === 'Pria' ? 'Laki-laki' : 'Perempuan'; @@ -223,7 +223,7 @@ export default function IPKJenisKelaminChart({ tahunAngkatan }: Props) { } setCategories(labels); - // Untuk bar chart, kita memerlukan array dari objects + // Untuk bar chart, kita memerlukan array dari objek setSeries([{ name: 'Rata-rata IPK', data: values diff --git a/components/charts/IPKLulusTepatChart.tsx b/components/charts/IPKLulusTepatChart.tsx index 242b11d..163e916 100644 --- a/components/charts/IPKLulusTepatChart.tsx +++ b/components/charts/IPKLulusTepatChart.tsx @@ -6,7 +6,7 @@ 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 +// Import ApexCharts secara dinamis untuk menghindari masalah SSR const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface IPKLulusTepatData { @@ -138,7 +138,7 @@ export default function IPKLulusTepatChart({ selectedYear }: IPKLulusTepatChartP left: 0 } }, - colors: ['#3B82F6'], // Blue color for line + colors: ['#3B82F6'], // Warna biru untuk garis tooltip: { theme: theme === 'dark' ? 'dark' : 'light', y: { @@ -160,7 +160,7 @@ export default function IPKLulusTepatChart({ selectedYear }: IPKLulusTepatChartP } }); - // Update theme when it changes + // Perbarui tema saat berubah useEffect(() => { const currentTheme = theme; setOptions(prev => ({ @@ -248,7 +248,7 @@ export default function IPKLulusTepatChart({ selectedYear }: IPKLulusTepatChartP const fetchedData: IPKLulusTepatData[] = await response.json(); setData(fetchedData); - // Process data for chart + // Proses data untuk chart const tahunAngkatan = fetchedData.map(item => item.tahun_angkatan); const rataRataIPK = fetchedData.map(item => item.rata_rata_ipk); @@ -264,7 +264,7 @@ export default function IPKLulusTepatChart({ selectedYear }: IPKLulusTepatChartP }, })); } catch (error) { - setError(error instanceof Error ? error.message : 'An error occurred'); + setError(error instanceof Error ? error.message : 'Terjadi kesalahan'); console.error('Error fetching data:', error); } finally { setLoading(false); diff --git a/components/charts/IPKPrestasiChart.tsx b/components/charts/IPKPrestasiChart.tsx index 192e0df..b6dd6bb 100644 --- a/components/charts/IPKPrestasiChart.tsx +++ b/components/charts/IPKPrestasiChart.tsx @@ -6,7 +6,7 @@ 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 +// Import ApexCharts secara dinamis untuk menghindari masalah SSR const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface IPKPrestasiData { @@ -161,7 +161,7 @@ export default function IPKPrestasiChart({ selectedJenisPrestasi }: Props) { } }); - // Update theme when it changes + // Perbarui tema saat berubah useEffect(() => { const currentTheme = theme; setOptions(prev => ({ @@ -250,15 +250,15 @@ export default function IPKPrestasiChart({ selectedJenisPrestasi }: Props) { const result = await response.json(); if (!Array.isArray(result)) { - throw new Error('Invalid data format received from server'); + throw new Error('Format data tidak valid diterima dari server'); } setData(result); - // Sort data by tahun_angkatan in ascending order + // Urutkan data berdasarkan tahun_angkatan secara ascending const sortedData = [...result].sort((a, b) => a.tahun_angkatan - b.tahun_angkatan); - // Process data for chart + // Proses data untuk chart const tahunAngkatan = sortedData.map(item => item.tahun_angkatan); const rataRataIPK = sortedData.map(item => item.rata_rata_ipk); @@ -275,7 +275,7 @@ export default function IPKPrestasiChart({ selectedJenisPrestasi }: Props) { })); } catch (err) { console.error('Error in fetchData:', err); - setError(err instanceof Error ? err.message : 'An error occurred while fetching data'); + setError(err instanceof Error ? err.message : 'Terjadi kesalahan saat mengambil data'); } finally { setLoading(false); } diff --git a/components/charts/IpkStatusChart.tsx b/components/charts/IpkStatusChart.tsx index d20e52e..44f400d 100644 --- a/components/charts/IpkStatusChart.tsx +++ b/components/charts/IpkStatusChart.tsx @@ -6,7 +6,7 @@ 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 +// Import ApexCharts secara dinamis untuk menghindari masalah SSR const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface IpkStatusData { @@ -53,10 +53,10 @@ export default function IpkStatusChart({ selectedYear, selectedStatus }: Props) if (!Array.isArray(result)) { console.error('Invalid data format:', result); - throw new Error('Invalid data format received from server'); + throw new Error('Format data tidak valid diterima dari server'); } - // Sort data by tahun_angkatan + // Urutkan data berdasarkan tahun_angkatan const sortedData = result.sort((a: IpkStatusData, b: IpkStatusData) => a.tahun_angkatan - b.tahun_angkatan ); @@ -65,7 +65,7 @@ export default function IpkStatusChart({ selectedYear, selectedStatus }: Props) setData(sortedData); } catch (err) { console.error('Error in fetchData:', err); - setError(err instanceof Error ? err.message : 'An error occurred while fetching data'); + setError(err instanceof Error ? err.message : 'Terjadi kesalahan saat mengambil data'); } finally { setLoading(false); } @@ -74,7 +74,7 @@ export default function IpkStatusChart({ selectedYear, selectedStatus }: Props) fetchData(); }, [selectedYear, selectedStatus]); - // Log data changes + // Log perubahan data useEffect(() => { console.log('Current data state:', data); }, [data]); @@ -219,7 +219,7 @@ export default function IpkStatusChart({ selectedYear, selectedStatus }: Props) } }; - // Process data for series + // Proses data untuk series const processSeriesData = () => { return [{ name: 'Rata-rata IPK', diff --git a/components/charts/StatistikMahasiswaChart.tsx b/components/charts/StatistikMahasiswaChart.tsx index 5decb1a..9ed9e16 100644 --- a/components/charts/StatistikMahasiswaChart.tsx +++ b/components/charts/StatistikMahasiswaChart.tsx @@ -8,7 +8,7 @@ import { useTheme } from "next-themes"; import { ExternalLink } from "lucide-react"; import Link from "next/link"; -// Import ApexCharts secara dinamis untuk menghindari error SSR +// Import ApexCharts secara dinamis untuk menghindari masalah SSR const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface MahasiswaStatistik { @@ -174,7 +174,7 @@ export default function StatistikMahasiswaChart({ const statistikData = await statistikResponse.json(); setStatistikData(statistikData); } catch (err) { - setError(err instanceof Error ? err.message : 'An error occurred'); + setError(err instanceof Error ? err.message : 'Terjadi kesalahan'); console.error('Error fetching data:', err); } finally { setLoading(false); @@ -184,7 +184,7 @@ export default function StatistikMahasiswaChart({ fetchData(); }, []); - // Update theme when it changes + // Perbarui tema saat berubah useEffect(() => { const currentTheme = theme; const textColor = currentTheme === 'dark' ? '#fff' : '#000'; @@ -253,7 +253,7 @@ export default function StatistikMahasiswaChart({ })); }, [theme]); - // Update categories when data changes + // Perbarui kategori saat data berubah useEffect(() => { if (statistikData.length > 0) { diff --git a/components/charts/StatistikPerAngkatanChart.tsx b/components/charts/StatistikPerAngkatanChart.tsx index d6dfb1a..0ba2efb 100644 --- a/components/charts/StatistikPerAngkatanChart.tsx +++ b/components/charts/StatistikPerAngkatanChart.tsx @@ -38,13 +38,13 @@ export default function StatistikPerAngkatanChart({ tahunAngkatan }: Props) { const result = await response.json(); if (!Array.isArray(result)) { - throw new Error('Invalid data format received from server'); + throw new Error('Format data tidak valid diterima dari server'); } setStatistikData(result); } catch (err) { console.error('Error in fetchData:', err); - setError(err instanceof Error ? err.message : 'An error occurred while fetching data'); + setError(err instanceof Error ? err.message : 'Terjadi kesalahan saat mengambil data'); } finally { setLoading(false); } @@ -119,7 +119,7 @@ export default function StatistikPerAngkatanChart({ tahunAngkatan }: Props) { } }); - // Update theme when it changes + // Perbarui tema saat berubah useEffect(() => { const currentTheme = theme; const textColor = currentTheme === 'dark' ? '#fff' : '#000'; @@ -152,7 +152,7 @@ export default function StatistikPerAngkatanChart({ tahunAngkatan }: Props) { })); }, [theme]); - // Update dataLabels formatter when data changes + // Perbarui formatter dataLabels saat data berubah useEffect(() => { if (statistikData.length > 0) { setChartOptions(prev => ({