revisi ini
This commit is contained in:
@@ -78,11 +78,6 @@ export async function GET(request: NextRequest) {
|
||||
mata_kuliah!inner(kode_mk, nama_mk)
|
||||
`);
|
||||
|
||||
// Add search condition if provided
|
||||
if (search) {
|
||||
query = query.or(`mahasiswa.nim.ilike.%${search}%,mahasiswa.nama.ilike.%${search}%,mata_kuliah.kode_mk.ilike.%${search}%,mata_kuliah.nama_mk.ilike.%${search}%`);
|
||||
}
|
||||
|
||||
// Add semester filter if provided
|
||||
if (semester && semester !== 'all') {
|
||||
query = query.eq('semester', parseInt(semester));
|
||||
@@ -94,7 +89,7 @@ export async function GET(request: NextRequest) {
|
||||
}
|
||||
|
||||
// Add order by
|
||||
query = query.order('semester', { ascending: true }).order('mahasiswa(nim)', { ascending: true });
|
||||
query = query.order('semester', { ascending: true });
|
||||
|
||||
const { data, error } = await query;
|
||||
|
||||
@@ -104,7 +99,7 @@ export async function GET(request: NextRequest) {
|
||||
}
|
||||
|
||||
// Transformasi data untuk meratakan field yang di-join
|
||||
const transformedData = data.map((item: any) => ({
|
||||
let transformedData = data.map((item: any) => ({
|
||||
...item,
|
||||
nim: item.mahasiswa?.nim || '',
|
||||
nama: item.mahasiswa?.nama || '',
|
||||
@@ -115,6 +110,27 @@ export async function GET(request: NextRequest) {
|
||||
return rest;
|
||||
});
|
||||
|
||||
// Client-side search filtering (untuk joined tables)
|
||||
if (search) {
|
||||
const searchLower = search.toLowerCase();
|
||||
transformedData = transformedData.filter((item: any) => {
|
||||
return (
|
||||
item.nim?.toLowerCase().includes(searchLower) ||
|
||||
item.nama?.toLowerCase().includes(searchLower) ||
|
||||
item.kode_mk?.toLowerCase().includes(searchLower) ||
|
||||
item.nama_mk?.toLowerCase().includes(searchLower)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Sort by nim after filtering
|
||||
transformedData.sort((a: any, b: any) => {
|
||||
if (a.semester !== b.semester) {
|
||||
return a.semester - b.semester;
|
||||
}
|
||||
return a.nim.localeCompare(b.nim);
|
||||
});
|
||||
|
||||
return NextResponse.json(transformedData);
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -241,7 +241,7 @@ export async function POST(request: NextRequest) {
|
||||
const nimToIdMap = new Map(existingMahasiswa?.map(m => [m.nim, m.id_mahasiswa]) || []);
|
||||
const kodeMKToIdMap = new Map(existingMataKuliah?.map(mk => [mk.kode_mk, mk.id_mk]) || []);
|
||||
|
||||
// Process data for insertion
|
||||
// Process data for insertion/update
|
||||
const insertData: any[] = [];
|
||||
const validationErrors: string[] = [];
|
||||
|
||||
@@ -279,26 +279,88 @@ export async function POST(request: NextRequest) {
|
||||
);
|
||||
}
|
||||
|
||||
// Insert data to database
|
||||
let successCount = 0;
|
||||
if (insertData.length > 0) {
|
||||
// Fetch existing nilai_mahasiswa to determine which to update vs insert
|
||||
const { data: existingNilai, error: fetchNilaiError } = await supabase
|
||||
.from('nilai_mahasiswa')
|
||||
.select('id_nilai, id_mahasiswa, id_mk');
|
||||
|
||||
if (fetchNilaiError) {
|
||||
return NextResponse.json(
|
||||
{ message: 'Failed to fetch existing nilai data' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
// Create map of existing nilai: "id_mahasiswa-id_mk" -> id_nilai
|
||||
const existingNilaiMap = new Map(
|
||||
(existingNilai || []).map(n => [`${n.id_mahasiswa}-${n.id_mk}`, n.id_nilai])
|
||||
);
|
||||
|
||||
// Separate data into updates and inserts
|
||||
const dataToUpdate: any[] = [];
|
||||
const dataToInsert: any[] = [];
|
||||
|
||||
for (const data of insertData) {
|
||||
const key = `${data.id_mahasiswa}-${data.id_mk}`;
|
||||
const existingId = existingNilaiMap.get(key);
|
||||
|
||||
if (existingId) {
|
||||
// Data exists, prepare for update
|
||||
dataToUpdate.push({
|
||||
id_nilai: existingId,
|
||||
...data,
|
||||
updated_at: new Date().toISOString()
|
||||
});
|
||||
} else {
|
||||
// Data doesn't exist, prepare for insert
|
||||
dataToInsert.push(data);
|
||||
}
|
||||
}
|
||||
|
||||
let insertCount = 0;
|
||||
let updateCount = 0;
|
||||
|
||||
// Perform batch insert
|
||||
if (dataToInsert.length > 0) {
|
||||
const { error: insertError } = await supabase
|
||||
.from('nilai_mahasiswa')
|
||||
.insert(insertData);
|
||||
.insert(dataToInsert);
|
||||
|
||||
if (insertError) {
|
||||
console.error('Insert error:', insertError);
|
||||
return NextResponse.json(
|
||||
{ message: 'Failed to insert data to database' },
|
||||
{ message: 'Failed to insert data to database', error: insertError.message },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
successCount = insertData.length;
|
||||
insertCount = dataToInsert.length;
|
||||
}
|
||||
|
||||
// Perform batch update (one by one because Supabase doesn't support batch update easily)
|
||||
if (dataToUpdate.length > 0) {
|
||||
for (const data of dataToUpdate) {
|
||||
const { id_nilai, ...updateFields } = data;
|
||||
|
||||
const { error: updateError } = await supabase
|
||||
.from('nilai_mahasiswa')
|
||||
.update(updateFields)
|
||||
.eq('id_nilai', id_nilai);
|
||||
|
||||
if (updateError) {
|
||||
console.error('Update error:', updateError);
|
||||
// Continue with other updates even if one fails
|
||||
} else {
|
||||
updateCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
message: 'Upload completed',
|
||||
successCount,
|
||||
inserted: insertCount,
|
||||
updated: updateCount,
|
||||
totalProcessed: insertCount + updateCount,
|
||||
totalRows: processedData.length
|
||||
});
|
||||
|
||||
|
||||
@@ -72,7 +72,21 @@ export default function UploadFileNilaiMahasiswa({ onUploadSuccess }: UploadFile
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
showSuccess("Berhasil!", `${result.successCount} nilai mahasiswa berhasil diimport`);
|
||||
// Create success message based on insert and update counts
|
||||
const inserted = result.inserted || 0;
|
||||
const updated = result.updated || 0;
|
||||
const total = inserted + updated;
|
||||
|
||||
let successMessage = `${total} nilai mahasiswa berhasil diproses`;
|
||||
if (inserted > 0 && updated > 0) {
|
||||
successMessage += ` (${inserted} ditambahkan, ${updated} diperbarui)`;
|
||||
} else if (inserted > 0) {
|
||||
successMessage += ` (${inserted} ditambahkan)`;
|
||||
} else if (updated > 0) {
|
||||
successMessage += ` (${updated} diperbarui)`;
|
||||
}
|
||||
|
||||
showSuccess("Berhasil!", successMessage);
|
||||
onUploadSuccess();
|
||||
setIsDialogOpen(false);
|
||||
setSelectedFile(null);
|
||||
|
||||
Reference in New Issue
Block a user