input('per_page', 7); $perPage = in_array($perPage, [5, 7]) ? $perPage : 7; $search = trim((string) $request->input('search', '')); $query = RiwayatRekomendasi::with('user:id,name,email') ->orderBy('created_at', 'desc'); if ($search !== '') { $query->where(function ($q) use ($search) { $q->where('hasil_rekomendasi_jurusan', 'like', "%{$search}%") ->orWhereHas('user', function ($user) use ($search) { $user->where('name', 'like', "%{$search}%") ->orWhere('email', 'like', "%{$search}%"); }); }); } $riwayat = $query->paginate($perPage); $riwayat->getCollection()->transform(function ($item) { return [ 'id' => $item->id, 'tanggal' => $item->created_at ? $item->created_at->format('d M Y') : '-', 'jam' => $item->created_at ? $item->created_at->format('H:i') : '-', 'nama_siswa' => $item->user ? $item->user->name : 'Siswa Tidak Diketahui', 'email_siswa' => $item->user ? $item->user->email : '-', 'hasil' => $item->hasil_rekomendasi_jurusan ?? 'Belum ada hasil', 'akurasi_prediksi' => $this->getAkurasiPrediksi($item), 'minat_utama' => $this->getMinatUtama($item), 'rata_nilai' => $this->getRataNilai($item), ]; }); return response()->json([ 'success' => true, 'data' => $riwayat->items(), 'current_page' => $riwayat->currentPage(), 'last_page' => $riwayat->lastPage(), 'per_page' => $riwayat->perPage(), 'total' => $riwayat->total(), 'from' => $riwayat->firstItem(), 'to' => $riwayat->lastItem(), ], 200); } catch (Exception $e) { return response()->json([ 'success' => false, 'message' => 'Error: ' . $e->getMessage() ], 500); } } public function show($id) { try { $detail = RiwayatRekomendasi::with('user:id,name,email')->findOrFail($id); return response()->json([ 'success' => true, 'data' => [ 'id' => $detail->id, 'tanggal' => $detail->created_at ? $detail->created_at->format('d M Y H:i:s') : '-', 'nama_siswa' => $detail->user ? $detail->user->name : 'Siswa Tidak Diketahui', 'email_siswa' => $detail->user ? $detail->user->email : '-', 'hasil_rekomendasi' => $detail->hasil_rekomendasi_jurusan ?? 'Belum ada hasil', 'akurasi_prediksi' => $this->getAkurasiPrediksi($detail), 'minat_utama' => $this->getMinatUtama($detail), 'rata_nilai' => $this->getRataNilai($detail), 'kondisi_ekonomi' => $this->getLabelEkonomi($detail->gaji_ortu), 'gaji_ortu' => $detail->gaji_ortu, 'nilai_ringkas' => [ 'Matematika' => $detail->matematika, 'B. Indonesia' => $detail->bahasa_indonesia, 'B. Inggris' => $detail->bahasa_inggris, 'Fisika' => $detail->fisika, 'Kimia' => $detail->kimia, 'Biologi' => $detail->biologi, 'Ekonomi' => $detail->ekonomi_mapel, 'Informatika' => $detail->informatika, ], 'riasec' => [ 'Realistic' => $detail->riasec_r, 'Investigative' => $detail->riasec_i, 'Artistic' => $detail->riasec_a, 'Social' => $detail->riasec_s, 'Enterprising' => $detail->riasec_e, 'Conventional' => $detail->riasec_c, ], ] ], 200); } catch (Exception $e) { return response()->json([ 'success' => false, 'message' => 'Data detail tidak ditemukan: ' . $e->getMessage() ], 404); } } private function getAkurasiPrediksi($riwayat): ?float { $tableName = (new RiwayatRekomendasi())->getTable(); if (!Schema::hasColumn($tableName, 'akurasi_prediksi')) { return null; } if ($riwayat->akurasi_prediksi === null) { return null; } return round((float) $riwayat->akurasi_prediksi, 2); } private function getRataNilai($riwayat): float { $nilai = [ $riwayat->agama, $riwayat->pkn, $riwayat->bahasa_indonesia, $riwayat->bahasa_inggris, $riwayat->matematika, $riwayat->fisika, $riwayat->kimia, $riwayat->biologi, $riwayat->sejarah, $riwayat->geografi, $riwayat->ekonomi_mapel, $riwayat->sosiologi, $riwayat->seni_budaya, $riwayat->pjok, $riwayat->informatika, ]; $nilai = array_filter($nilai, fn ($item) => $item !== null); if (count($nilai) === 0) { return 0; } return round(array_sum($nilai) / count($nilai), 2); } private function getMinatUtama($riwayat): string { $scores = [ 'Teknis & Lapangan' => (float) $riwayat->riasec_r, 'Sains, Riset & Analitis' => (float) $riwayat->riasec_i, 'Kreatif & Desain' => (float) $riwayat->riasec_a, 'Sosial & Pelayanan' => (float) $riwayat->riasec_s, 'Bisnis & Kepemimpinan' => (float) $riwayat->riasec_e, 'Administratif & Terstruktur' => (float) $riwayat->riasec_c, ]; arsort($scores); return array_key_first($scores) ?? 'Belum teridentifikasi'; } private function getLabelEkonomi($gaji): string { $gaji = (float) $gaji; if ($gaji < 2000000) { return 'Kurang Mampu'; } if ($gaji <= 5000000) { return 'Menengah'; } return 'Mampu'; } }