leaderboard admin guru
This commit is contained in:
parent
62d15959a6
commit
2835406564
|
|
@ -4,15 +4,50 @@
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Leaderboard;
|
||||
use App\Models\Kelas;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class LeaderboardController extends Controller
|
||||
{
|
||||
public function index()
|
||||
public function index(Request $request)
|
||||
{
|
||||
$leaderboards = Leaderboard::orderBy('ranking')
|
||||
->orderByDesc('total_exp')
|
||||
->paginate(10);
|
||||
$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);
|
||||
$idKelas = $request->input('id_kelas');
|
||||
|
||||
return view('admin.leaderboard.index', compact('leaderboards'));
|
||||
$kelasList = Kelas::orderBy('tingkat')->orderBy('nama_kelas')->get();
|
||||
|
||||
$query = Leaderboard::with(['siswa', 'kelas'])
|
||||
->where('semester', $semester)
|
||||
->where('tahun_ajaran', $tahunAjaran);
|
||||
|
||||
if ($idKelas) {
|
||||
$query->where('id_kelas', $idKelas);
|
||||
}
|
||||
|
||||
$leaderboard = $query->orderBy('total_exp', 'desc')->get()
|
||||
->map(function ($item, $i) {
|
||||
return [
|
||||
'ranking' => $i + 1,
|
||||
'nama' => optional($item->siswa)->nama ?? '-',
|
||||
'nisn' => optional($item->siswa)->nisn ?? '-',
|
||||
'nama_kelas' => optional($item->kelas)->nama_kelas ?? '-',
|
||||
'exp' => $item->total_exp,
|
||||
];
|
||||
});
|
||||
|
||||
// Tahun ajaran list untuk dropdown (5 tahun ke belakang)
|
||||
$tahunList = [];
|
||||
for ($y = $now->year; $y >= $now->year - 4; $y--) {
|
||||
$tahunList[] = $y . '/' . ($y + 1);
|
||||
}
|
||||
|
||||
return view('admin.leaderboard.index', compact(
|
||||
'leaderboard', 'kelasList', 'semester', 'tahunAjaran', 'idKelas', 'tahunList'
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,15 +4,64 @@
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Leaderboard;
|
||||
use App\Models\Kelas;
|
||||
use App\Models\Mengajar;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class LeaderboardController extends Controller
|
||||
{
|
||||
public function index()
|
||||
public function index(Request $request)
|
||||
{
|
||||
$leaderboards = Leaderboard::orderBy('ranking')
|
||||
->orderByDesc('total_exp')
|
||||
->paginate(10);
|
||||
/** @var \App\Models\Guru $guru */
|
||||
$guru = Auth::guard('guru')->user();
|
||||
|
||||
return view('admin.leaderboard.index', compact('leaderboards'));
|
||||
$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);
|
||||
|
||||
// Kelas yang diajar guru ini
|
||||
$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) {
|
||||
$leaderboard = Leaderboard::with(['siswa', 'kelas'])
|
||||
->where('id_kelas', $idKelas)
|
||||
->where('semester', $semester)
|
||||
->where('tahun_ajaran', $tahunAjaran)
|
||||
->orderBy('total_exp', 'desc')
|
||||
->get()
|
||||
->map(function ($item, $i) {
|
||||
return [
|
||||
'ranking' => $i + 1,
|
||||
'nama' => optional($item->siswa)->nama ?? '-',
|
||||
'nisn' => optional($item->siswa)->nisn ?? '-',
|
||||
'nama_kelas' => optional($item->kelas)->nama_kelas ?? '-',
|
||||
'exp' => $item->total_exp,
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
$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'
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,33 +2,229 @@
|
|||
|
||||
@section('title', 'Leaderboard')
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
.page-title { font-size: 28px; font-weight: 800; margin-top: -20px; margin-bottom: 6px; }
|
||||
.page-subtitle { font-size: 14px; color: #64748b; margin-bottom: 24px; }
|
||||
|
||||
.filter-card {
|
||||
background: white;
|
||||
border-radius: 16px;
|
||||
border: 2px solid #e5e5e5;
|
||||
padding: 18px 22px;
|
||||
margin-bottom: 24px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 14px;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.filter-group { display: flex; flex-direction: column; gap: 5px; }
|
||||
.filter-group label { font-size: 12px; font-weight: 600; color: #64748b; }
|
||||
.filter-group select {
|
||||
border: 2px solid #e2e8f0;
|
||||
border-radius: 10px;
|
||||
padding: 7px 12px;
|
||||
font-size: 13px;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
color: #1e293b;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn-filter {
|
||||
background: #2b8ef3;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
padding: 9px 20px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Podium */
|
||||
.podium-wrap {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.podium-item { display: flex; flex-direction: column; align-items: center; gap: 8px; }
|
||||
|
||||
.podium-avatar {
|
||||
width: 56px; height: 56px;
|
||||
border-radius: 50%;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 22px; font-weight: 800; color: white;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.podium-crown { position: absolute; top: -16px; font-size: 18px; }
|
||||
|
||||
.rank-1 .podium-avatar { background: linear-gradient(135deg,#f59e0b,#d97706); width:68px; height:68px; font-size:26px; }
|
||||
.rank-2 .podium-avatar { background: linear-gradient(135deg,#94a3b8,#64748b); }
|
||||
.rank-3 .podium-avatar { background: linear-gradient(135deg,#f97316,#ea580c); }
|
||||
|
||||
.podium-name { font-size: 13px; font-weight: 700; color: #1e293b; text-align: center; max-width: 90px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.podium-kelas { font-size: 11px; color: #94a3b8; }
|
||||
.podium-exp { font-size: 12px; color: #64748b; }
|
||||
|
||||
.podium-bar { border-radius: 12px 12px 0 0; width: 80px; display: flex; align-items: center; justify-content: center; font-size: 20px; font-weight: 800; color: white; }
|
||||
.rank-1 .podium-bar { height: 80px; background: linear-gradient(135deg,#f59e0b,#d97706); }
|
||||
.rank-2 .podium-bar { height: 60px; background: linear-gradient(135deg,#94a3b8,#64748b); }
|
||||
.rank-3 .podium-bar { height: 44px; background: linear-gradient(135deg,#f97316,#ea580c); }
|
||||
|
||||
/* Tabel */
|
||||
.custom-card { background: white; border-radius: 20px; border: 2px solid #e5e5e5; padding: 22px; }
|
||||
.section-title { font-size: 15px; font-weight: 700; color: #1e293b; margin-bottom: 16px; }
|
||||
|
||||
.lb-row { display: flex; align-items: center; gap: 14px; padding: 11px 14px; border-radius: 12px; margin-bottom: 6px; transition: background 0.15s; }
|
||||
.lb-row:hover { background: #f8fafc; }
|
||||
|
||||
.lb-rank {
|
||||
width: 32px; height: 32px; border-radius: 50%;
|
||||
background: #e2e8f0;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 13px; font-weight: 700; color: #64748b; flex-shrink: 0;
|
||||
}
|
||||
|
||||
.lb-rank.gold { background: #fef3c7; color: #d97706; }
|
||||
.lb-rank.silver { background: #f1f5f9; color: #64748b; }
|
||||
.lb-rank.bronze { background: #ffedd5; color: #ea580c; }
|
||||
|
||||
.lb-nama { flex: 1; font-size: 14px; font-weight: 600; color: #1e293b; }
|
||||
.lb-nisn { font-size: 12px; color: #94a3b8; }
|
||||
.lb-kelas { font-size: 12px; color: #64748b; background: #f1f5f9; padding: 2px 8px; border-radius: 99px; }
|
||||
.lb-exp { font-size: 14px; font-weight: 700; color: #2b8ef3; }
|
||||
|
||||
.semester-badge { display: inline-block; background: #e0f2fe; color: #0369a1; font-size: 12px; font-weight: 700; padding: 4px 12px; border-radius: 99px; margin-bottom: 20px; }
|
||||
.empty-state { text-align: center; padding: 40px 20px; color: #94a3b8; }
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
|
||||
<h3 class="mb-4">🏆 Leaderboard</h3>
|
||||
<h3 class="page-title">🏅 Leaderboard</h3>
|
||||
<p class="page-subtitle">Peringkat siswa berdasarkan total EXP yang dikumpulkan.</p>
|
||||
|
||||
<table class="table table-striped bg-white">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Ranking</th>
|
||||
<th>NISN</th>
|
||||
<th>Total EXP</th>
|
||||
<th>Semester</th>
|
||||
<th>Tahun Ajaran</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($leaderboards as $lb)
|
||||
<tr>
|
||||
<td>{{ $lb->ranking }}</td>
|
||||
<td>{{ $lb->nisn }}</td>
|
||||
<td>{{ $lb->total_exp }}</td>
|
||||
<td>{{ $lb->semester }}</td>
|
||||
<td>{{ $lb->tahun_ajaran }}</td>
|
||||
</tr>
|
||||
{{-- Filter --}}
|
||||
<form method="GET" action="{{ route('admin.leaderboard.index') }}">
|
||||
<div class="filter-card">
|
||||
<div class="filter-group">
|
||||
<label>Semester</label>
|
||||
<select name="semester">
|
||||
<option value="1" {{ $semester == '1' ? 'selected' : '' }}>Semester 1</option>
|
||||
<option value="2" {{ $semester == '2' ? 'selected' : '' }}>Semester 2</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="filter-group">
|
||||
<label>Tahun Ajaran</label>
|
||||
<select name="tahun_ajaran">
|
||||
@foreach($tahunList as $thn)
|
||||
<option value="{{ $thn }}" {{ $tahunAjaran == $thn ? 'selected' : '' }}>{{ $thn }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="filter-group">
|
||||
<label>Kelas</label>
|
||||
<select name="id_kelas">
|
||||
<option value="">Semua Kelas</option>
|
||||
@foreach($kelasList as $kelas)
|
||||
<option value="{{ $kelas->id_kelas }}" {{ $idKelas == $kelas->id_kelas ? 'selected' : '' }}>
|
||||
{{ $kelas->nama_kelas }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn-filter">Tampilkan</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<span class="semester-badge">Semester {{ $semester }} · {{ $tahunAjaran }}{{ $idKelas ? ' · ' . ($kelasList->firstWhere('id_kelas', $idKelas)?->nama_kelas ?? '') : ' · Semua Kelas' }}</span>
|
||||
|
||||
@if($leaderboard->isEmpty())
|
||||
<div class="empty-state">
|
||||
<div style="font-size:52px;margin-bottom:12px">📊</div>
|
||||
<p style="font-size:15px;font-weight:600;color:#475569">Belum ada data leaderboard.</p>
|
||||
<p style="font-size:13px">Belum ada siswa yang menyelesaikan challenge pada periode ini.</p>
|
||||
</div>
|
||||
@else
|
||||
|
||||
{{-- Podium --}}
|
||||
@php
|
||||
$first = $leaderboard->firstWhere('ranking', 1);
|
||||
$second = $leaderboard->firstWhere('ranking', 2);
|
||||
$third = $leaderboard->firstWhere('ranking', 3);
|
||||
@endphp
|
||||
|
||||
@if($first)
|
||||
<div class="podium-wrap">
|
||||
@if($second)
|
||||
<div class="podium-item rank-2">
|
||||
<div class="podium-avatar">{{ strtoupper(substr($second['nama'],0,1)) }}</div>
|
||||
<div class="podium-name">{{ $second['nama'] }}</div>
|
||||
<div class="podium-kelas">{{ $second['nama_kelas'] }}</div>
|
||||
<div class="podium-exp">⭐ {{ number_format($second['exp']) }}</div>
|
||||
<div class="podium-bar">2</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="podium-item rank-1">
|
||||
<div class="podium-avatar">
|
||||
<span class="podium-crown">👑</span>
|
||||
{{ strtoupper(substr($first['nama'],0,1)) }}
|
||||
</div>
|
||||
<div class="podium-name">{{ $first['nama'] }}</div>
|
||||
<div class="podium-kelas">{{ $first['nama_kelas'] }}</div>
|
||||
<div class="podium-exp">⭐ {{ number_format($first['exp']) }}</div>
|
||||
<div class="podium-bar">1</div>
|
||||
</div>
|
||||
|
||||
@if($third)
|
||||
<div class="podium-item rank-3">
|
||||
<div class="podium-avatar">{{ strtoupper(substr($third['nama'],0,1)) }}</div>
|
||||
<div class="podium-name">{{ $third['nama'] }}</div>
|
||||
<div class="podium-kelas">{{ $third['nama_kelas'] }}</div>
|
||||
<div class="podium-exp">⭐ {{ number_format($third['exp']) }}</div>
|
||||
<div class="podium-bar">3</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Tabel --}}
|
||||
<div class="custom-card">
|
||||
<p class="section-title">📋 Semua Peringkat ({{ $leaderboard->count() }} siswa)</p>
|
||||
|
||||
@foreach($leaderboard as $item)
|
||||
@php
|
||||
$rankClass = match($item['ranking']) { 1=>'gold', 2=>'silver', 3=>'bronze', default=>'' };
|
||||
@endphp
|
||||
<div class="lb-row">
|
||||
<div class="lb-rank {{ $rankClass }}">
|
||||
@if($item['ranking']===1) 🥇
|
||||
@elseif($item['ranking']===2) 🥈
|
||||
@elseif($item['ranking']===3) 🥉
|
||||
@else {{ $item['ranking'] }}
|
||||
@endif
|
||||
</div>
|
||||
<div style="flex:1">
|
||||
<div class="lb-nama">{{ $item['nama'] }}</div>
|
||||
<div class="lb-nisn">{{ $item['nisn'] }}</div>
|
||||
</div>
|
||||
<span class="lb-kelas">{{ $item['nama_kelas'] }}</span>
|
||||
<div class="lb-exp">⭐ {{ number_format($item['exp']) }}</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{ $leaderboards->links() }}
|
||||
@endif
|
||||
|
||||
@endsection
|
||||
@endsection
|
||||
|
|
@ -2,33 +2,228 @@
|
|||
|
||||
@section('title', 'Leaderboard')
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
.page-title { font-size: 28px; font-weight: 800; margin-top: -20px; margin-bottom: 6px; }
|
||||
.page-subtitle { font-size: 14px; color: #64748b; margin-bottom: 24px; }
|
||||
|
||||
.filter-card {
|
||||
background: white;
|
||||
border-radius: 16px;
|
||||
border: 2px solid #e5e5e5;
|
||||
padding: 18px 22px;
|
||||
margin-bottom: 24px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 14px;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.filter-group { display: flex; flex-direction: column; gap: 5px; }
|
||||
.filter-group label { font-size: 12px; font-weight: 600; color: #64748b; }
|
||||
.filter-group select {
|
||||
border: 2px solid #e2e8f0;
|
||||
border-radius: 10px;
|
||||
padding: 7px 12px;
|
||||
font-size: 13px;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
color: #1e293b;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn-filter {
|
||||
background: #2b8ef3;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
padding: 9px 20px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.podium-wrap { display: flex; align-items: flex-end; justify-content: center; gap: 12px; margin-bottom: 28px; }
|
||||
.podium-item { display: flex; flex-direction: column; align-items: center; gap: 8px; }
|
||||
|
||||
.podium-avatar {
|
||||
width: 56px; height: 56px; border-radius: 50%;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 22px; font-weight: 800; color: white; position: relative;
|
||||
}
|
||||
|
||||
.podium-crown { position: absolute; top: -16px; font-size: 18px; }
|
||||
|
||||
.rank-1 .podium-avatar { background: linear-gradient(135deg,#f59e0b,#d97706); width:68px; height:68px; font-size:26px; }
|
||||
.rank-2 .podium-avatar { background: linear-gradient(135deg,#94a3b8,#64748b); }
|
||||
.rank-3 .podium-avatar { background: linear-gradient(135deg,#f97316,#ea580c); }
|
||||
|
||||
.podium-name { font-size: 13px; font-weight: 700; color: #1e293b; text-align: center; max-width: 90px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.podium-exp { font-size: 12px; color: #64748b; }
|
||||
|
||||
.podium-bar { border-radius: 12px 12px 0 0; width: 80px; display: flex; align-items: center; justify-content: center; font-size: 20px; font-weight: 800; color: white; }
|
||||
.rank-1 .podium-bar { height: 80px; background: linear-gradient(135deg,#f59e0b,#d97706); }
|
||||
.rank-2 .podium-bar { height: 60px; background: linear-gradient(135deg,#94a3b8,#64748b); }
|
||||
.rank-3 .podium-bar { height: 44px; background: linear-gradient(135deg,#f97316,#ea580c); }
|
||||
|
||||
.custom-card { background: white; border-radius: 20px; border: 2px solid #e5e5e5; padding: 22px; }
|
||||
.section-title { font-size: 15px; font-weight: 700; color: #1e293b; margin-bottom: 16px; }
|
||||
|
||||
.lb-row { display: flex; align-items: center; gap: 14px; padding: 11px 14px; border-radius: 12px; margin-bottom: 6px; transition: background 0.15s; }
|
||||
.lb-row:hover { background: #f8fafc; }
|
||||
|
||||
.lb-rank {
|
||||
width: 32px; height: 32px; border-radius: 50%;
|
||||
background: #e2e8f0;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 13px; font-weight: 700; color: #64748b; flex-shrink: 0;
|
||||
}
|
||||
|
||||
.lb-rank.gold { background: #fef3c7; color: #d97706; }
|
||||
.lb-rank.silver { background: #f1f5f9; color: #64748b; }
|
||||
.lb-rank.bronze { background: #ffedd5; color: #ea580c; }
|
||||
|
||||
.lb-nama { flex: 1; font-size: 14px; font-weight: 600; color: #1e293b; }
|
||||
.lb-nisn { font-size: 12px; color: #94a3b8; }
|
||||
.lb-exp { font-size: 14px; font-weight: 700; color: #2b8ef3; }
|
||||
|
||||
.semester-badge { display: inline-block; background: #e0f2fe; color: #0369a1; font-size: 12px; font-weight: 700; padding: 4px 12px; border-radius: 99px; margin-bottom: 20px; }
|
||||
.empty-state { text-align: center; padding: 40px 20px; color: #94a3b8; }
|
||||
|
||||
.no-kelas-box {
|
||||
background: #fff7ed;
|
||||
border: 2px solid #fed7aa;
|
||||
border-radius: 16px;
|
||||
padding: 24px;
|
||||
text-align: center;
|
||||
color: #c2410c;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
|
||||
<h3 class="mb-4">🏆 Leaderboard</h3>
|
||||
<h3 class="page-title">🏅 Leaderboard</h3>
|
||||
<p class="page-subtitle">Peringkat siswa di kelas yang Anda ajar.</p>
|
||||
|
||||
<table class="table table-striped bg-white">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Ranking</th>
|
||||
<th>NISN</th>
|
||||
<th>Total EXP</th>
|
||||
<th>Semester</th>
|
||||
<th>Tahun Ajaran</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($leaderboards as $lb)
|
||||
<tr>
|
||||
<td>{{ $lb->ranking }}</td>
|
||||
<td>{{ $lb->nisn }}</td>
|
||||
<td>{{ $lb->total_exp }}</td>
|
||||
<td>{{ $lb->semester }}</td>
|
||||
<td>{{ $lb->tahun_ajaran }}</td>
|
||||
</tr>
|
||||
@if($kelasList->isEmpty())
|
||||
<div class="no-kelas-box">
|
||||
⚠️ Anda belum mengajar kelas manapun. Hubungi admin untuk mengatur jadwal mengajar.
|
||||
</div>
|
||||
@else
|
||||
|
||||
{{-- Filter --}}
|
||||
<form method="GET" action="{{ route('guru.leaderboard.index') }}">
|
||||
<div class="filter-card">
|
||||
<div class="filter-group">
|
||||
<label>Kelas</label>
|
||||
<select name="id_kelas">
|
||||
@foreach($kelasList as $kelas)
|
||||
<option value="{{ $kelas->id_kelas }}" {{ $idKelas == $kelas->id_kelas ? 'selected' : '' }}>
|
||||
{{ $kelas->nama_kelas }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="filter-group">
|
||||
<label>Semester</label>
|
||||
<select name="semester">
|
||||
<option value="1" {{ $semester == '1' ? 'selected' : '' }}>Semester 1</option>
|
||||
<option value="2" {{ $semester == '2' ? 'selected' : '' }}>Semester 2</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="filter-group">
|
||||
<label>Tahun Ajaran</label>
|
||||
<select name="tahun_ajaran">
|
||||
@foreach($tahunList as $thn)
|
||||
<option value="{{ $thn }}" {{ $tahunAjaran == $thn ? 'selected' : '' }}>{{ $thn }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn-filter">Tampilkan</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@php $namaKelas = $kelasList->firstWhere('id_kelas', $idKelas)?->nama_kelas ?? '-'; @endphp
|
||||
<span class="semester-badge">{{ $namaKelas }} · Semester {{ $semester }} · {{ $tahunAjaran }}</span>
|
||||
|
||||
@if($leaderboard->isEmpty())
|
||||
<div class="empty-state">
|
||||
<div style="font-size:52px;margin-bottom:12px">📊</div>
|
||||
<p style="font-size:15px;font-weight:600;color:#475569">Belum ada data leaderboard.</p>
|
||||
<p style="font-size:13px">Belum ada siswa yang menyelesaikan challenge pada periode ini.</p>
|
||||
</div>
|
||||
@else
|
||||
|
||||
{{-- Podium --}}
|
||||
@php
|
||||
$first = $leaderboard->firstWhere('ranking', 1);
|
||||
$second = $leaderboard->firstWhere('ranking', 2);
|
||||
$third = $leaderboard->firstWhere('ranking', 3);
|
||||
@endphp
|
||||
|
||||
@if($first)
|
||||
<div class="podium-wrap">
|
||||
@if($second)
|
||||
<div class="podium-item rank-2">
|
||||
<div class="podium-avatar">{{ strtoupper(substr($second['nama'],0,1)) }}</div>
|
||||
<div class="podium-name">{{ $second['nama'] }}</div>
|
||||
<div class="podium-exp">⭐ {{ number_format($second['exp']) }}</div>
|
||||
<div class="podium-bar">2</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="podium-item rank-1">
|
||||
<div class="podium-avatar">
|
||||
<span class="podium-crown">👑</span>
|
||||
{{ strtoupper(substr($first['nama'],0,1)) }}
|
||||
</div>
|
||||
<div class="podium-name">{{ $first['nama'] }}</div>
|
||||
<div class="podium-exp">⭐ {{ number_format($first['exp']) }}</div>
|
||||
<div class="podium-bar">1</div>
|
||||
</div>
|
||||
|
||||
@if($third)
|
||||
<div class="podium-item rank-3">
|
||||
<div class="podium-avatar">{{ strtoupper(substr($third['nama'],0,1)) }}</div>
|
||||
<div class="podium-name">{{ $third['nama'] }}</div>
|
||||
<div class="podium-exp">⭐ {{ number_format($third['exp']) }}</div>
|
||||
<div class="podium-bar">3</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Tabel --}}
|
||||
<div class="custom-card">
|
||||
<p class="section-title">📋 Semua Peringkat ({{ $leaderboard->count() }} siswa)</p>
|
||||
|
||||
@foreach($leaderboard as $item)
|
||||
@php $rankClass = match($item['ranking']) { 1=>'gold', 2=>'silver', 3=>'bronze', default=>'' }; @endphp
|
||||
<div class="lb-row">
|
||||
<div class="lb-rank {{ $rankClass }}">
|
||||
@if($item['ranking']===1) 🥇
|
||||
@elseif($item['ranking']===2) 🥈
|
||||
@elseif($item['ranking']===3) 🥉
|
||||
@else {{ $item['ranking'] }}
|
||||
@endif
|
||||
</div>
|
||||
<div style="flex:1">
|
||||
<div class="lb-nama">{{ $item['nama'] }}</div>
|
||||
<div class="lb-nisn">{{ $item['nisn'] }}</div>
|
||||
</div>
|
||||
<div class="lb-exp">⭐ {{ number_format($item['exp']) }}</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{ $leaderboards->links() }}
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@endsection
|
||||
@endsection
|
||||
Loading…
Reference in New Issue