a lot of things fixed

This commit is contained in:
RetasyaSalsabila 2026-04-15 21:16:51 +07:00
parent 3dfee40774
commit 8afad7d12b
12 changed files with 229 additions and 84 deletions

View File

@ -66,7 +66,7 @@ public function update(Request $request, $id_kelas)
'max:50',
Rule::unique('kelas')->where(function ($query) use ($request) {
return $query->where('tingkat', $request->tingkat);
})->ignore($id, 'id_kelas'),
})->ignore($id_kelas, 'id_kelas'),
],
'tingkat' => 'required|in:X,XI,XII',
], [

View File

@ -25,16 +25,11 @@ public function index()
/** @var \App\Models\Siswa $siswa */
$siswa = Auth::guard('siswa')->user();
// =============================================
// 1. TUGAS — yang belum dikumpulkan siswa ini
// dan deadline belum lewat
// =============================================
// tugas
// id_tugas yang sudah dikumpulkan siswa ini
$sudahDikumpulkan = PengumpulanTugas::where('id_siswa', $siswa->id_siswa)
->pluck('id_tugas');
// Tugas untuk kelas siswa yang belum dikumpulkan
$tugasRaw = Tugas::with(['mengajar.mapel'])
->whereNotIn('id_tugas', $sudahDikumpulkan)
->where('deadline', '>=', Carbon::now())
@ -45,7 +40,6 @@ public function index()
->take(5)
->get();
// Kelompokkan per tanggal deadline
$tugasList = [];
foreach ($tugasRaw as $tugas) {
$tgl = Carbon::parse($tugas->deadline)
@ -55,15 +49,15 @@ public function index()
$namaMapel = optional(optional($tugas->mengajar)->mapel)->nama_mapel ?? '-';
$tugasList[$tgl][] = [
'id_tugas' => $tugas->id_tugas, // tambah ini
'jam' => Carbon::parse($tugas->deadline)->format('H.i'),
'nama' => $tugas->judul_tugas,
'mapel' => 'Belum · ' . $namaMapel,
];
}
// =============================================
// 2. CHALLENGE MINGGUAN
// =============================================
// challenge mingguan
$startMinggu = Carbon::now()->startOfWeek();
$endMinggu = Carbon::now()->endOfWeek();
@ -81,17 +75,14 @@ public function index()
->whereBetween('waktu_submit', [$startMinggu, $endMinggu])
->count();
// =============================================
// 3. TUGAS SELESAI MINGGU INI (mascot speech bubble)
// =============================================
// mascot
$tugasSelesai = PengumpulanTugas::where('id_siswa', $siswa->id_siswa)
->whereIn('status', ['dikumpulkan', 'terlambat'])
->whereBetween('tanggal_submit', [$startMinggu, $endMinggu])
->count();
// =============================================
// 4. LEADERBOARD — top 3 kelas siswa yang login
// =============================================
// leaderboard
$leaderboardRaw = Leaderboard::with('siswa')
->where('id_kelas', $siswa->id_kelas)
->orderBy('total_exp', 'desc')

View File

@ -58,6 +58,7 @@ public function index()
'sudah_kumpul' => !is_null($pengumpulan),
'lampiran' => $pengumpulan?->lampiran_tugas,
'exp' => $pengumpulan?->exp ?? 0,
'file_tugas' => $tugas->lampiran,
];
});

View File

@ -15,7 +15,6 @@ class Kelas extends Model
protected $keyType = 'int';
protected $fillable = [
'id_kelas',
'nama_kelas',
'tingkat',
];

View File

@ -0,0 +1,23 @@
// database/migrations/xxxx_fix_kelas_autoincrement.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
public function up(): void
{
// Hapus kolom sisa refactor kalau masih ada
if (Schema::hasColumn('kelas', 'id_kelas_old')) {
Schema::table('kelas', function ($table) {
$table->dropColumn('id_kelas_old');
});
}
// Reset AUTO_INCREMENT ke angka setelah max id_kelas yang ada
DB::statement('ALTER TABLE kelas AUTO_INCREMENT = 1');
}
public function down(): void {}
};

View File

@ -545,22 +545,11 @@
placeholder="Deskripsi singkat challenge (opsional)"></textarea>
</div>
<div class="row g-3 mb-3">
<div class="col-6">
<div class="mb-3">
<label>Tenggat Waktu <span class="text-danger">*</span></label>
<input type="datetime-local" name="tenggat_waktu" id="tambah-tenggat" class="form-control"
min="{{ now()->format('Y-m-d\TH:i') }}">
</div>
<div class="col-6">
<label>Badge Reward</label>
<select name="id_badge" class="form-control">
<option value="">-- Tanpa Badge --</option>
@foreach($badges as $badge)
<option value="{{ $badge->id_badge }}">{{ $badge->nama_badge }}</option>
@endforeach
</select>
</div>
</div>
<div class="section-divider">
<img src="{{ asset('images/icon/gurud/school.png') }}" class="inline-icon" alt="Kelas"> Target Kelas

View File

@ -32,6 +32,7 @@
display: inline-flex;
align-items: center;
gap: 6px;
width: 145px;
}
.btn-materi {
@ -167,7 +168,7 @@
@section('content')
<h3 class="page-title">MATA PELAJARAN YANG ANDA AJAR</h3>
<h3 class="page-title">MATA PELAJARAN</h3>
@if(session('success'))
<div class="alert-success-custom">
@ -219,7 +220,7 @@
{{-- AKSI --}}
<td>
<div class="d-flex flex-wrap gap-1 justify-content-center">
<div class="d-flex flex-column gap-1">
<button class="action-btn btn-materi"
onclick="openMateriModal(
'{{ addslashes(optional($mapel)->nama_mapel) }}',

View File

@ -117,11 +117,8 @@
<h3 class="page-title">
<img src="{{ asset('images/icon/gurud/file.png') }}" class="icon-inline" alt="Ikon file">
History Materi
HISTORY MATERI
</h3>
<p style="color:#64748b;font-size:14px;margin-bottom:20px">
Semua materi yang pernah Anda upload.
</p>
@if(session('success'))
<div class="alert-success-custom">

View File

@ -136,11 +136,8 @@
<h3 class="page-title">
<img src="{{ asset('images/icon/gurud/history.png') }}" class="icon-inline" alt="Ikon history">
History Tugas
HISTORY TUGAS
</h3>
<p style="color:#64748b;font-size:14px;margin-bottom:20px">
Semua tugas yang pernah Anda buat.
</p>
@if(session('success'))
<div class="alert-success-custom">
@ -219,7 +216,7 @@
<div class="d-flex gap-1 justify-content-center">
<a href="{{ route('guru.tugas.detail', $tugas->id_tugas) }}"
class="btn-detail">
<img src="{{ asset('images/icon/gurud/detail.png') }}" class="icon-inline" alt="Detail tugas"> Detail
<img src="{{ asset('images/icon/gurud/eye.png') }}" class="icon-inline" alt="Detail tugas"> Detail
</a>
<form action="{{ route('guru.tugas.destroy', $tugas->id_tugas) }}"
method="POST"

View File

@ -121,6 +121,12 @@
padding: 20px 0;
}
.tugas-link {
text-decoration: none;
color: inherit;
display: block;
}
/* KALENDER */
.calendar-nav {
display: flex;
@ -341,6 +347,7 @@
@forelse($tugasList as $tanggal => $items)
<p class="tugas-date-label">{{ $tanggal }}</p>
@foreach($items as $item)
<a href="{{ route('siswa.tugas.show', $item['id_tugas']) }}" class="tugas-link">
<div class="tugas-item">
<span class="tugas-time">{{ $item['jam'] }}</span>
<img src="{{ asset('images/icon/siswadb/buku.png') }}" alt="Ikon tugas" class="icon-md">
@ -349,7 +356,8 @@
<p class="tugas-mapel">{{ $item['mapel'] }}</p>
</div>
</div>
@endforeach
</a>
@endforeach
@empty
<div class="tugas-empty">
<img src="{{ asset('images/icon/siswadb/confetti.png') }}" alt="Semua tugas selesai" class="icon-sm">

View File

@ -203,6 +203,10 @@
border-radius: 99px;
margin-top: 4px;
}
.medal-icon{
width: 40px;
height: 40px;
}
/* ── Modal Badge Global (leaderboard) ── */
.lb-badge-modal-overlay {
@ -424,7 +428,7 @@
@if($semuaBadgeLayout->isNotEmpty())
<div class="modal-badge-section">
<hr class="modal-divider">
<div class="modal-badge-title">🏅 Badge Koleksiku</div>
<div class="modal-badge-title"><img src="{{ asset('images/icon/gurud/medal-pita.png') }}" class="medal-icon" alt="Medal">Badge Koleksiku</div>
<div class="modal-badge-grid">
@foreach($semuaBadgeLayout as $b)
@php $dimiliki = in_array($b->id_badge, $idBadgeDimiliki); @endphp
@ -455,7 +459,7 @@
<div class="lb-badge-modal-label">Badge Baru Diraih!</div>
<div class="lb-badge-modal-list" id="lbBadgeList"></div>
<button class="lb-badge-modal-btn" onclick="dismissLbBadgeModal()">
Sip, lanjut! 🚀
Sip, lanjut! <img src="{{ asset('images/icon/lp/rocket.png') }}" alt="Let's Go!">
</button>
</div>
</div>

View File

@ -76,6 +76,108 @@
margin-top: 12px;
}
.tugas-bottom-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-bottom: 20px;
}
.lampiran-card {
background: #fff;
border-radius: 20px;
padding: 28px;
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
display: flex;
flex-direction: column;
}
.lampiran-title {
font-size: 17px;
font-weight: 700;
color: #1e293b;
margin: 0 0 20px;
display: flex;
align-items: center;
gap: 8px;
}
.lampiran-file-box {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: #f0f7ff;
border-radius: 14px;
padding: 28px 20px;
text-align: center;
gap: 12px;
}
.lampiran-file-icon {
width: 56px;
height: 56px;
}
.lampiran-file-name {
font-size: 13px;
font-weight: 600;
color: #1e293b;
word-break: break-all;
}
.lampiran-file-ext {
font-size: 11px;
color: #94a3b8;
background: #e2e8f0;
padding: 2px 10px;
border-radius: 99px;
}
.btn-download {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
margin-top: 16px;
background: #2b8ef3;
color: white;
padding: 10px 20px;
border-radius: 10px;
font-weight: 600;
font-size: 13px;
text-decoration: none;
transition: background 0.2s;
width: 100%;
}
.btn-download:hover {
background: #1a7ae0;
color: white;
}
.no-lampiran {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: #f8fafc;
border-radius: 14px;
padding: 28px 20px;
text-align: center;
color: #94a3b8;
font-size: 13px;
gap: 8px;
}
@media (max-width: 768px) {
.tugas-bottom-grid {
grid-template-columns: 1fr;
}
}
/* SUBMIT FORM */
.submit-card {
background: #fff;
@ -315,7 +417,6 @@
{!! nl2br(e($tugas->keterangan)) !!}
</div>
@endif
</div>
{{-- WARNING TERLAMBAT --}}
@if($terlambat && !$sudahKumpul)
@ -351,62 +452,96 @@
EXP akan diberikan setelah guru menilai tugasmu.
</p>
@endif
@if($pengumpulan->lampiran_tugas)
<a href="{{ asset('storage/' . $pengumpulan->lampiran_tugas) }}"
target="_blank"
style="display:inline-flex;align-items:center;gap:6px;margin-top:14px;
background:#fff;color:#2b8ef3;padding:8px 18px;border-radius:10px;
font-weight:600;font-size:13px;text-decoration:none;">
📎 Lihat File yang Dikumpulkan
<img src="{{ asset('images/icon/gurud/link.png') }}" alt="Lampiran" class="icon-md"> Lihat File yang Dikumpulkan
</a>
@endif
</div>
{{-- FORM SUBMIT --}}
@else
<div class="submit-card">
<p class="submit-title">
<img src="{{ asset('images/icon/siswat/upload.png') }}" alt="Upload jawaban" class="icon-md">
Upload Jawaban
</p>
{{-- GRID: LAMPIRAN GURU (kiri) + UPLOAD SISWA (kanan) --}}
<div class="tugas-bottom-grid">
<form action="{{ route('siswa.tugas.submit', $tugas->id_tugas) }}"
method="POST"
enctype="multipart/form-data"
id="submitForm">
@csrf
{{-- KIRI: Lampiran dari Guru --}}
<div class="lampiran-card">
<p class="lampiran-title">
<img src="{{ asset('images/icon/gurud/link.png') }}" alt="Lampiran" class="icon-md">
File dari Guru
</p>
@error('lampiran_tugas')
<div class="alert-error" style="margin-bottom:16px">
<img src="{{ asset('images/icon/siswat/x.png') }}" alt="Error validasi" class="icon-sm">
{{ $message }}
@if($tugas->lampiran)
@php
$namaFile = basename($tugas->lampiran);
$ext = strtoupper(pathinfo($namaFile, PATHINFO_EXTENSION));
@endphp
<div class="lampiran-file-box">
<img src="{{ asset('images/icon/gurud/link.png') }}" alt="File" class="lampiran-file-icon">
<span class="lampiran-file-name">{{ $namaFile }}</span>
<span class="lampiran-file-ext">{{ $ext }}</span>
</div>
@enderror
<div class="upload-area" id="uploadArea">
<input type="file"
name="lampiran_tugas"
id="fileInput"
accept=".pdf,.doc,.docx,.jpg,.jpeg,.png"
required>
<div class="upload-icon">
<img src="{{ asset('images/icon/siswat/upload.png') }}" alt="Upload file" class="icon-mascot" style="width:48px; margin-top:0;">
<a href="{{ asset('storage/' . $tugas->lampiran) }}"
target="_blank"
class="btn-download">
<img src="{{ asset('images/icon/gurud/download.png') }}" alt="Download" class="icon-md"> Download File Tugas
</a>
@else
<div class="no-lampiran">
<span style="font-size:32px"><img src="{{ asset('images/icon/gurud/mailbox.png') }}" alt="Mailbox" class="icon-md"></span>
Tidak ada file lampiran dari guru.
</div>
<p class="upload-text"><strong>Klik untuk pilih file</strong> atau drag & drop di sini</p>
<p class="upload-hint">PDF, DOC, DOCX, JPG, PNG &bull; Maks. 5MB</p>
</div>
@endif
</div>
<div class="file-preview" id="filePreview">
<img src="{{ asset('images/icon/siswat/buku1.png') }}" alt="File terpilih" class="icon-md">
<span class="file-preview-name" id="fileName">-</span>
<span class="file-preview-size" id="fileSize">-</span>
</div>
{{-- KANAN: Upload Jawaban --}}
<div class="submit-card" style="margin-bottom:0">
<p class="submit-title">
<img src="{{ asset('images/icon/siswat/upload.png') }}" alt="Upload jawaban" class="icon-md">
Upload Jawaban
</p>
<form action="{{ route('siswa.tugas.submit', $tugas->id_tugas) }}"
method="POST"
enctype="multipart/form-data"
id="submitForm">
@csrf
@error('lampiran_tugas')
<div class="alert-error" style="margin-bottom:16px">
<img src="{{ asset('images/icon/siswat/x.png') }}" alt="Error validasi" class="icon-sm">
{{ $message }}
</div>
@enderror
<div class="upload-area" id="uploadArea">
<input type="file"
name="lampiran_tugas"
id="fileInput"
accept=".pdf,.doc,.docx,.jpg,.jpeg,.png"
required>
<div class="upload-icon">
<img src="{{ asset('images/icon/siswat/upload.png') }}" alt="Upload file" class="icon-mascot" style="width:48px; margin-top:0;">
</div>
<p class="upload-text"><strong>Klik untuk pilih file</strong> atau drag & drop di sini</p>
<p class="upload-hint">PDF, DOC, DOCX, JPG, PNG &bull; Maks. 5MB</p>
</div>
<div class="file-preview" id="filePreview">
<img src="{{ asset('images/icon/siswat/buku1.png') }}" alt="File terpilih" class="icon-md">
<span class="file-preview-name" id="fileName">-</span>
<span class="file-preview-size" id="fileSize">-</span>
</div>
<button type="submit" class="btn-submit" id="submitBtn" disabled>
Kumpulkan Tugas
</button>
</form>
</div>
<button type="submit" class="btn-submit" id="submitBtn" disabled>
Kumpulkan Tugas
</button>
</form>
</div>
@endif