MIF_E31230356/app/Http/Controllers/Guru/LeaderboardController.php

132 lines
4.8 KiB
PHP

<?php
namespace App\Http\Controllers\Guru;
use App\Http\Controllers\Controller;
use App\Models\Kelas;
use App\Models\Mengajar;
use App\Models\Siswa;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class LeaderboardController extends Controller
{
private function hitungExpSiswa(int $idSiswa, int $idKelas): int
{
$now = Carbon::now();
// ── 1. EXP dari challenge ─────────────────────────────────────────
$expChallenge = 0;
$pesertaList = DB::table('peserta_challenges')
->where('id_siswa', $idSiswa)
->get();
foreach ($pesertaList as $peserta) {
$jawaban = json_decode($peserta->jawaban, true) ?? [];
$soalList = DB::table('soal_challenge')
->where('id_challenge', $peserta->id_challenge)
->get();
foreach ($soalList as $soal) {
$jwb = $jawaban[$soal->id_soal] ?? null;
if ($jwb && strtoupper($jwb) === strtoupper($soal->jawaban_benar)) {
$expChallenge += 1; // +1 per soal benar
}
}
}
// ── 2. EXP dari tugas ─────────────────────────────────────────────
$tugasList = DB::table('tugas')
->join('mengajars', 'tugas.id_mengajar', '=', 'mengajars.id_mengajar')
->where('mengajars.id_kelas', $idKelas)
->select('tugas.id_tugas', 'tugas.deadline')
->get();
$expTugas = 0;
foreach ($tugasList as $tugas) {
$deadline = Carbon::parse($tugas->deadline);
$pengumpulan = DB::table('pengumpulan_tugas')
->where('id_tugas', $tugas->id_tugas)
->where('id_siswa', $idSiswa)
->first();
if ($pengumpulan && $pengumpulan->lampiran_tugas !== null) {
$tanggalSubmit = Carbon::parse($pengumpulan->tanggal_submit);
if ($tanggalSubmit->lessThanOrEqualTo($deadline)) {
$expTugas += 10; // Tepat waktu → +10
} else {
$hariTerlambat = $deadline->diffInDays($tanggalSubmit); // ← dibalik
if ($hariTerlambat <= 1) {
$expTugas += 5; // Terlambat ≤ 1 hari → +5
} elseif ($hariTerlambat <= 3) {
$expTugas += 1; // Terlambat 2-3 hari → +3
} else {
$expTugas -= 5; // Lewat grace period > 3 hari → dianggap tidak kumpul
}
}
} elseif ($now->greaterThan($deadline)) {
// Tidak kumpul sama sekali & deadline lewat → -5
$expTugas -= 5;
}
}
return max(0, $expChallenge + $expTugas);
}
public function index(Request $request)
{
/** @var \App\Models\Guru $guru */
$guru = Auth::guard('guru')->user();
$now = Carbon::now();
$semester = $request->input('semester', $now->month >= 7 ? '1' : '2');
$tahunAjaran = $request->input('tahun_ajaran', $now->month >= 7
? $now->year . '/' . ($now->year + 1)
: ($now->year - 1) . '/' . $now->year);
$idKelasList = Mengajar::where('id_guru', $guru->id_guru)
->pluck('id_kelas')
->unique()
->toArray();
$idKelas = $request->input('id_kelas', $idKelasList[0] ?? null);
$kelasList = Kelas::whereIn('id_kelas', $idKelasList)
->orderBy('tingkat')->orderBy('nama_kelas')
->get();
$leaderboard = collect();
if ($idKelas) {
$semuaSiswa = Siswa::where('id_kelas', $idKelas)->get();
$leaderboard = $semuaSiswa->map(function ($s) {
return [
'id_siswa' => $s->id_siswa,
'nama' => $s->nama,
'nisn' => $s->nisn,
'foto_profil' => $s->foto_profil,
'nama_kelas' => $s->kelas->nama_kelas ?? '-',
'exp' => $this->hitungExpSiswa($s->id_siswa, $s->id_kelas),
];
})
->sortByDesc('exp')
->values()
->map(function ($item, $i) {
$item['ranking'] = $i + 1;
return $item;
});
}
$tahunList = [];
for ($y = $now->year; $y >= $now->year - 4; $y--) {
$tahunList[] = $y . '/' . ($y + 1);
}
return view('guru.leaderboard.index', compact(
'leaderboard', 'kelasList', 'semester', 'tahunAjaran', 'idKelas', 'tahunList'
));
}
}