170 lines
6.0 KiB
PHP
170 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Siswa;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Badge;
|
|
use App\Models\SiswaBadge;
|
|
use App\Services\BadgeService;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Carbon\Carbon;
|
|
use App\Models\Tugas;
|
|
use App\Models\PengumpulanTugas;
|
|
|
|
class TugasController extends Controller
|
|
{
|
|
public function __construct()
|
|
{
|
|
$this->middleware('auth:siswa');
|
|
}
|
|
|
|
/**
|
|
* Daftar semua tugas untuk kelas siswa
|
|
*/
|
|
public function index()
|
|
{
|
|
$siswa = Auth::guard('siswa')->user();
|
|
|
|
$semuaTugas = Tugas::with(['mengajar.mapel', 'mengajar.guru'])
|
|
->whereHas('mengajar', function ($q) use ($siswa) {
|
|
$q->where('id_kelas', $siswa->id_kelas);
|
|
})
|
|
->orderBy('deadline', 'asc')
|
|
->get();
|
|
|
|
$tugasList = $semuaTugas->map(function ($tugas) use ($siswa) {
|
|
$pengumpulan = PengumpulanTugas::where('id_tugas', $tugas->id_tugas)
|
|
->where('id_siswa', $siswa->id_siswa)
|
|
->first();
|
|
|
|
$now = Carbon::now();
|
|
$deadline = Carbon::parse($tugas->deadline);
|
|
|
|
if ($pengumpulan) {
|
|
$status = $pengumpulan->status;
|
|
} else {
|
|
$status = $now->greaterThan($deadline) ? 'terlambat' : 'belum';
|
|
}
|
|
|
|
return [
|
|
'id_tugas' => $tugas->id_tugas,
|
|
'judul' => $tugas->judul_tugas,
|
|
'keterangan' => $tugas->keterangan,
|
|
'deadline' => $deadline,
|
|
'nama_mapel' => optional(optional($tugas->mengajar)->mapel)->nama_mapel ?? '-',
|
|
'nama_guru' => optional(optional($tugas->mengajar)->guru)->nama ?? '-',
|
|
'status' => $status,
|
|
'sudah_kumpul' => !is_null($pengumpulan),
|
|
'lampiran' => $pengumpulan?->lampiran_tugas,
|
|
'exp' => $pengumpulan?->exp ?? 0,
|
|
'file_tugas' => $tugas->lampiran,
|
|
];
|
|
});
|
|
|
|
$tugasBelum = $tugasList->filter(fn($t) => !$t['sudah_kumpul'] && $t['status'] !== 'terlambat');
|
|
$tugasTerlambat = $tugasList->filter(fn($t) => !$t['sudah_kumpul'] && $t['status'] === 'terlambat');
|
|
$tugasSelesai = $tugasList->filter(fn($t) => $t['sudah_kumpul']);
|
|
|
|
return view('siswa.tugas.index', compact('tugasBelum', 'tugasTerlambat', 'tugasSelesai'));
|
|
}
|
|
|
|
/**
|
|
* Detail tugas + form submit
|
|
*/
|
|
public function show($id_tugas)
|
|
{
|
|
$siswa = Auth::guard('siswa')->user();
|
|
|
|
$tugas = Tugas::with(['mengajar.mapel', 'mengajar.guru'])
|
|
->whereHas('mengajar', function ($q) use ($siswa) {
|
|
$q->where('id_kelas', $siswa->id_kelas);
|
|
})
|
|
->where('id_tugas', $id_tugas)
|
|
->firstOrFail();
|
|
|
|
$pengumpulan = PengumpulanTugas::where('id_tugas', $id_tugas)
|
|
->where('id_siswa', $siswa->id_siswa)
|
|
->first();
|
|
|
|
$sudahKumpul = !is_null($pengumpulan);
|
|
$terlambat = Carbon::now()->greaterThan(Carbon::parse($tugas->deadline));
|
|
|
|
return view('siswa.tugas.show', compact('tugas', 'pengumpulan', 'sudahKumpul', 'terlambat'));
|
|
}
|
|
|
|
/**
|
|
* Submit / upload jawaban tugas
|
|
*/
|
|
public function submit(Request $request, $id_tugas)
|
|
{
|
|
$siswa = Auth::guard('siswa')->user();
|
|
|
|
$request->validate([
|
|
'lampiran_tugas' => 'required|file|mimes:pdf,doc,docx,jpg,jpeg,png|max:5120',
|
|
], [
|
|
'lampiran_tugas.required' => 'File jawaban wajib diupload.',
|
|
'lampiran_tugas.mimes' => 'Format file harus pdf, doc, docx, jpg, atau png.',
|
|
'lampiran_tugas.max' => 'Ukuran file maksimal 5MB.',
|
|
]);
|
|
|
|
$tugas = Tugas::whereHas('mengajar', function ($q) use ($siswa) {
|
|
$q->where('id_kelas', $siswa->id_kelas);
|
|
})
|
|
->where('id_tugas', $id_tugas)
|
|
->firstOrFail();
|
|
|
|
$sudahAda = PengumpulanTugas::where('id_tugas', $id_tugas)
|
|
->where('id_siswa', $siswa->id_siswa)
|
|
->exists();
|
|
|
|
if ($sudahAda) {
|
|
return back()->with('error', 'Kamu sudah mengumpulkan tugas ini.');
|
|
}
|
|
|
|
$file = $request->file('lampiran_tugas');
|
|
$filename = 'tugas_' . $siswa->id_siswa . '_' . $id_tugas . '_' . time() . '.' . $file->getClientOriginalExtension();
|
|
$path = $file->storeAs('pengumpulan_tugas', $filename, 'public');
|
|
|
|
$now = Carbon::now();
|
|
$deadline = Carbon::parse($tugas->deadline);
|
|
$status = $now->greaterThan($deadline) ? 'terlambat' : 'dikumpulkan';
|
|
|
|
PengumpulanTugas::create([
|
|
'id_tugas' => $id_tugas,
|
|
'id_siswa' => $siswa->id_siswa,
|
|
'lampiran_tugas' => $path,
|
|
'tanggal_submit' => $now,
|
|
'exp' => 0,
|
|
'status' => $status,
|
|
]);
|
|
|
|
// Cek & berikan badge tugas hanya jika tepat waktu
|
|
if ($status === 'dikumpulkan') {
|
|
// Snapshot badge sebelum pengecekan
|
|
$badgeSebelum = SiswaBadge::where('id_siswa', $siswa->id_siswa)
|
|
->pluck('id_badge')
|
|
->toArray();
|
|
|
|
app(BadgeService::class)->checkTugasBadges($siswa->id_siswa);
|
|
|
|
// Deteksi badge yang baru didapat
|
|
$badgeSesudah = SiswaBadge::where('id_siswa', $siswa->id_siswa)
|
|
->pluck('id_badge')
|
|
->toArray();
|
|
|
|
$idBadgeBaru = array_diff($badgeSesudah, $badgeSebelum);
|
|
|
|
if (!empty($idBadgeBaru)) {
|
|
$badgeBaru = Badge::whereIn('id_badge', $idBadgeBaru)->get();
|
|
session()->flash('badge_baru', $badgeBaru);
|
|
}
|
|
}
|
|
|
|
$pesan = $status === 'terlambat'
|
|
? 'Tugas berhasil dikumpulkan (terlambat).'
|
|
: 'Tugas berhasil dikumpulkan! 🎉';
|
|
|
|
return redirect()->route('siswa.tugas.index')->with('success', $pesan);
|
|
}
|
|
} |