user(); $now = Carbon::now(); $semester = $now->month >= 7 ? '1' : '2'; $tahunAjaran = $now->month >= 7 ? $now->year . '/' . ($now->year + 1) : ($now->year - 1) . '/' . $now->year; $leaderboard = Leaderboard::with('siswa') ->where('id_kelas', $siswa->id_kelas) ->where('semester', $semester) ->where('tahun_ajaran', $tahunAjaran) ->orderBy('total_exp', 'desc') ->get() ->map(function ($item, $i) { $fotoProfil = optional($item->siswa)->foto_profil; return [ 'ranking' => $i + 1, 'nama' => optional($item->siswa)->nama ?? '-', 'nisn' => optional($item->siswa)->nisn ?? '-', 'exp' => $item->total_exp, 'id_siswa' => $item->id_siswa, 'foto_profil' => $fotoProfil, 'foto_url' => $fotoProfil ? Storage::url($fotoProfil) : null, ]; }); $myRank = $leaderboard->firstWhere('id_siswa', $siswa->id_siswa); return compact('leaderboard', 'myRank', 'semester', 'tahunAjaran', 'siswa'); } public function index() { $data = $this->getData(); // Keluarkan 'siswa' dari data yang dikirim ke view (tidak dibutuhkan di view) unset($data['siswa']); return view('siswa.leaderboard.index', $data); } /** * Endpoint JSON untuk polling real-time. * Setiap kali dipanggil, badge leaderboard siswa yang sedang login * dievaluasi ulang (diberikan atau dicabut sesuai ranking saat ini). */ public function json() { $data = $this->getData(); $siswa = $data['siswa']; // Evaluasi badge leaderboard secara real-time untuk siswa yang sedang login app(BadgeService::class)->checkLeaderboardBadges( $siswa->id_siswa, $siswa->id_kelas ); unset($data['siswa']); return response()->json($data); } }