MIF_E31230356/resources/views/guru/mapel/index.blade.php

508 lines
19 KiB
PHP

@extends('guru.layouts.app')
@section('title', 'Daftar Mata Pelajaran')
@push('styles')
<style>
.page-title {
font-size: 22px;
font-weight: 800;
margin-bottom: 12px;
margin-top: -10px;
}
@media (min-width: 769px) {
.page-title { font-size: 30px; margin-top: -20px; margin-bottom: 10px; }
}
.custom-card {
background: white;
border-radius: 16px;
border: 2px solid #e5e5e5;
padding: 14px;
overflow-x: auto;
}
@media (min-width: 769px) { .custom-card { border-radius: 20px; padding: 25px; } }
.table-header { background: #a5e6ba; }
.action-btn {
padding: 7px 12px;
border-radius: 10px;
border: none;
font-size: 12px;
cursor: pointer;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 6px;
width: 100%;
font-family: 'Poppins', sans-serif;
font-weight: 500;
white-space: nowrap;
}
@media (min-width: 769px) { .action-btn { font-size: 13px; width: 145px; } }
.btn-materi { background: #2b8ef3; color: white; }
.btn-materi:hover { background: #1a7ae0; color: white; }
.btn-tugas { background: #f97316; color: white; }
.btn-tugas:hover { background: #ea6c0a; color: white; }
.btn-history-materi { background: #8b5cf6; color: white; }
.btn-history-materi:hover { background: #7c3aed; color: white; }
.btn-history-tugas { background: #14b8a6; color: white; }
.btn-history-tugas:hover { background: #0d9488; color: white; }
.kelas-badge {
display: inline-block;
background: #e6f0ff;
color: #1d4ed8;
font-size: 11px;
font-weight: 600;
padding: 3px 8px;
border-radius: 99px;
margin: 2px;
white-space: nowrap;
}
.table-responsive-custom { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table { min-width: 480px; }
/* ══════════════════════════════════════════
MODAL — SIMPLE CENTERED + SCROLLABLE BODY
══════════════════════════════════════════ */
.modal-content {
border-radius: 16px;
border: none;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
/* Batasi tinggi total modal */
max-height: 85vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
.modal-header-blue {
background: #2b8ef3;
color: white;
border-bottom: none;
border-radius: 16px 16px 0 0;
padding: 13px 16px;
flex-shrink: 0;
}
.modal-header-orange {
background: #f97316;
color: white;
border-bottom: none;
border-radius: 16px 16px 0 0;
padding: 13px 16px;
flex-shrink: 0;
}
.modal-header-blue .btn-close,
.modal-header-orange .btn-close { filter: brightness(0) invert(1); }
.modal-header-blue .modal-title,
.modal-header-orange .modal-title {
font-size: 14px;
font-weight: 700;
display: flex;
align-items: center;
gap: 7px;
color: white;
flex-wrap: wrap;
line-height: 1.4;
}
/* Body scroll */
.modal-body {
overflow-y: auto;
-webkit-overflow-scrolling: touch;
overscroll-behavior: contain;
flex: 1 1 auto;
padding: 14px 16px;
}
.modal-body::-webkit-scrollbar { width: 3px; }
.modal-body::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 99px; }
/* Footer fix */
.modal-footer {
flex-shrink: 0;
border-top: 2px solid #f1f5f9;
padding: 10px 16px;
background: white;
border-radius: 0 0 16px 16px;
}
/* Form elements */
.modal-body label {
font-weight: 600;
font-size: 12px;
color: #475569;
margin-bottom: 4px;
display: block;
}
/* font-size 16px cegah iOS auto-zoom */
.modal-body .form-control {
border-radius: 10px;
border: 2px solid #e2e8f0;
font-size: 16px;
padding: 8px 11px;
width: 100%;
transition: border-color 0.2s;
}
@media (min-width: 576px) { .modal-body .form-control { font-size: 14px; } }
.modal-body .form-control:focus {
border-color: #2b8ef3;
box-shadow: 0 0 0 3px rgba(43,142,243,0.12);
outline: none;
}
/* Textarea keterangan — kecil di HP, sedikit lebih besar di desktop */
textarea.form-control.textarea-keterangan {
resize: none;
height: 64px; /* ~2 baris di HP */
}
@media (min-width: 576px) {
textarea.form-control.textarea-keterangan { height: 80px; }
}
/* Upload area */
.upload-area {
border: 2px dashed #cbd5e1;
border-radius: 10px;
padding: 14px 12px;
text-align: center;
cursor: pointer;
position: relative;
transition: border-color 0.2s, background 0.2s;
-webkit-tap-highlight-color: transparent;
}
.upload-area:hover, .upload-area:active { border-color: #2b8ef3; background: #f0f7ff; }
.upload-area input[type="file"] {
position: absolute; inset: 0; opacity: 0;
cursor: pointer; width: 100%; height: 100%;
font-size: 16px;
}
.upload-icon { width: 28px; height: 28px; margin: 0 auto 5px; display: block; }
.upload-label { margin: 3px 0 0; font-size: 11px; color: #64748b; line-height: 1.4; }
.file-preview {
display: none; align-items: center; gap: 8px;
background: #f0f7ff; border-radius: 8px;
padding: 7px 10px; margin-top: 8px;
font-size: 11px; font-weight: 600; color: #1e293b;
word-break: break-all;
}
.file-preview.show { display: flex; }
/* Tombol footer */
.modal-footer .btn {
border-radius: 10px;
font-size: 13px;
font-weight: 700;
padding: 9px 18px;
}
/* Alerts */
.alert-success-custom {
background: #dcfce7; color: #166534;
border-radius: 10px; padding: 10px 14px;
margin-bottom: 14px; font-weight: 500; font-size: 13px;
display: flex; align-items: center; gap: 8px;
}
.alert-error-custom {
background: #fee2e2; color: #991b1b;
border-radius: 10px; padding: 10px 14px;
margin-bottom: 14px; font-weight: 500; font-size: 13px;
display: flex; align-items: center; gap: 8px;
}
@media (max-width: 576px) { .aksi-col { min-width: 160px; } }
</style>
@endpush
@section('content')
<h3 class="page-title">MATA PELAJARAN</h3>
@if(session('success'))
<div class="alert-success-custom">
<img src="{{ asset('images/icon/gurud/v.png') }}" class="icon-inline" alt="Berhasil">
{{ session('success') }}
</div>
@endif
@if(session('error'))
<div class="alert-error-custom">
<img src="{{ asset('images/icon/gurud/x.png') }}" class="icon-inline" alt="Gagal">
{{ session('error') }}
</div>
@endif
<div class="custom-card">
<div class="table-responsive-custom">
<table class="table text-center align-middle">
<thead class="table-header">
<tr>
<th>No</th>
<th>Nama Mata Pelajaran</th>
<th>Kelas yang Diajar</th>
<th class="aksi-col">Aksi</th>
</tr>
</thead>
<tbody>
@forelse($mengajars as $idMapel => $rows)
@php
$mapel = $rows->first()->mapel;
$kelasList = $rows->map(fn($m) => $m->kelas)->filter();
$mengajarOptions = $rows->map(fn($m) => [
'id_mengajar' => $m->id_mengajar,
'kelas' => optional($m->kelas)->tingkat . ' ' . optional($m->kelas)->nama_kelas,
]);
@endphp
<tr>
<td>{{ $loop->iteration }}</td>
<td style="text-align:left;font-weight:600;white-space:nowrap">{{ optional($mapel)->nama_mapel ?? '-' }}</td>
<td>
@foreach($kelasList as $kelas)
<span class="kelas-badge">{{ $kelas->tingkat }} {{ $kelas->nama_kelas }}</span>
@endforeach
</td>
<td>
<div class="d-flex flex-column gap-1 align-items-center">
<button class="action-btn btn-materi"
onclick="openMateriModal('{{ addslashes(optional($mapel)->nama_mapel) }}', {{ $mengajarOptions->toJson() }})">
<img src="{{ asset('images/icon/gurud/buku1.png') }}" class="icon-inline" alt="Upload materi">
Upload Materi
</button>
<button class="action-btn btn-tugas"
onclick="openTugasModal('{{ addslashes(optional($mapel)->nama_mapel) }}', {{ $mengajarOptions->toJson() }})">
<img src="{{ asset('images/icon/gurud/buku2.png') }}" class="icon-inline" alt="Buat tugas">
Buat Tugas
</button>
<a href="{{ route('guru.materi.history', ['id_mapel' => $idMapel]) }}" class="action-btn btn-history-materi">
<img src="{{ asset('images/icon/gurud/file.png') }}" class="icon-inline" alt="History materi">
History Materi
</a>
<a href="{{ route('guru.tugas.history', ['id_mapel' => $idMapel]) }}" class="action-btn btn-history-tugas">
<img src="{{ asset('images/icon/gurud/history.png') }}" class="icon-inline" alt="History tugas">
History Tugas
</a>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="4" class="text-muted py-4">Anda belum mengajar mata pelajaran apapun.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
{{-- ============================================================ --}}
{{-- MODAL UPLOAD MATERI --}}
{{-- ============================================================ --}}
<div class="modal fade" id="modalMateri" tabindex="-1">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header modal-header-blue">
<h5 class="modal-title">
<img src="{{ asset('images/icon/gurud/add-file.png') }}" class="icon-inline" alt="Upload">
Upload Materi <span id="materiMapelLabel"></span>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form action="{{ route('guru.materi.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="modal-body">
<div class="mb-3">
<label>Kelas Tujuan <span class="text-danger">*</span></label>
<select name="id_mengajar" id="materiMengajar" class="form-control" required>
<option value="">-- Pilih Kelas --</option>
</select>
<small class="text-muted" style="font-size:11px">Materi akan dikirim ke kelas yang dipilih.</small>
</div>
<div class="mb-3">
<label>Judul Materi <span class="text-danger">*</span></label>
<input type="text" name="judul_materi" class="form-control"
placeholder="Contoh: Pertemuan 1 - Pengantar Algoritma" required>
</div>
<div class="mb-3">
<label>Deskripsi</label>
<textarea name="deskripsi" class="form-control textarea-keterangan"
placeholder="Deskripsi singkat materi (opsional)"></textarea>
</div>
<div class="mb-1">
<label>File Materi <span class="text-muted fw-normal" style="font-size:11px">(PDF, DOC, PPT, JPG maks 10MB)</span></label>
<div class="upload-area">
<input type="file" name="lampiran_materi" id="materiFile"
accept=".pdf,.doc,.docx,.ppt,.pptx,.jpg,.jpeg,.png"
onchange="previewFile(this,'materiPreview','materiFileName')">
<img src="{{ asset('images/icon/gurud/cloud.png') }}" class="upload-icon" alt="Upload">
<p class="upload-label"><strong>Ketuk</strong> untuk pilih file</p>
</div>
<div class="file-preview" id="materiPreview">📎 <span id="materiFileName">-</span></div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Batal</button>
<button type="submit" class="btn btn-primary">Upload Materi</button>
</div>
</form>
</div>
</div>
</div>
{{-- ============================================================ --}}
{{-- MODAL BUAT TUGAS --}}
{{-- ============================================================ --}}
<div class="modal fade" id="modalTugas" tabindex="-1">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header modal-header-orange">
<h5 class="modal-title">
<img src="{{ asset('images/icon/gurud/buku2.png') }}" class="icon-inline" alt="Buat tugas">
Buat Tugas <span id="tugasMapelLabel"></span>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form action="{{ route('guru.tugas.store') }}" method="POST" enctype="multipart/form-data"
id="formBuatTugas">
@csrf
<div class="modal-body">
<div class="mb-3">
<label>Kelas Tujuan <span class="text-danger">*</span></label>
<select name="id_mengajar" id="tugasMengajar" class="form-control" required>
<option value="">-- Pilih Kelas --</option>
</select>
<small class="text-muted" style="font-size:11px">Tugas akan dikirim ke kelas yang dipilih.</small>
</div>
<div class="mb-3">
<label>Judul Tugas <span class="text-danger">*</span></label>
<input type="text" name="judul_tugas" class="form-control"
placeholder="Contoh: Latihan Soal Bab 3" required>
</div>
<div class="mb-3">
<label>Keterangan / Instruksi</label>
{{-- rows dikecilkan + class textarea-keterangan biar height terbatas --}}
<textarea name="keterangan" class="form-control textarea-keterangan"
placeholder="Instruksi pengerjaan tugas (opsional)"></textarea>
</div>
<div class="mb-3">
<label>Deadline <span class="text-danger">*</span></label>
<div class="row g-2">
<div class="col-6">
<input type="date" id="deadlineDate" class="form-control" required
min="{{ now()->format('Y-m-d') }}">
<small class="text-muted" style="font-size:11px">Tanggal</small>
</div>
<div class="col-6">
<input type="time" id="deadlineTime" class="form-control" required>
<small class="text-muted" style="font-size:11px">Jam (WIB)</small>
</div>
</div>
<input type="hidden" name="deadline" id="deadlineCombined">
</div>
<div class="mb-1">
<label>Lampiran <span class="text-muted fw-normal" style="font-size:11px">(Semua tipe maks 10MB, opsional)</span></label>
<div class="upload-area">
<input type="file" name="lampiran_tugas" id="tugasFile"
onchange="previewFile(this,'tugasPreview','tugasFileName')">
<img src="{{ asset('images/icon/gurud/link.png') }}" class="upload-icon" alt="Lampirkan">
<p class="upload-label"><strong>Ketuk</strong> untuk pilih file</p>
</div>
<div class="file-preview" id="tugasPreview">📎 <span id="tugasFileName">-</span></div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Batal</button>
<button type="submit" class="btn" style="background:#f97316;color:white;">Buat Tugas</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
function openMateriModal(namaMapel, mengajars) {
document.getElementById('materiMapelLabel').textContent = namaMapel;
const sel = document.getElementById('materiMengajar');
sel.innerHTML = '<option value="">-- Pilih Kelas --</option>';
mengajars.forEach(m => {
const o = document.createElement('option');
o.value = m.id_mengajar; o.textContent = m.kelas; sel.appendChild(o);
});
if (mengajars.length === 1) sel.value = mengajars[0].id_mengajar;
document.querySelector('#modalMateri input[name="judul_materi"]').value = '';
document.querySelector('#modalMateri textarea[name="deskripsi"]').value = '';
document.getElementById('materiPreview').classList.remove('show');
document.getElementById('materiFile').value = '';
new bootstrap.Modal(document.getElementById('modalMateri')).show();
}
function openTugasModal(namaMapel, mengajars) {
document.getElementById('tugasMapelLabel').textContent = namaMapel;
const sel = document.getElementById('tugasMengajar');
sel.innerHTML = '<option value="">-- Pilih Kelas --</option>';
mengajars.forEach(m => {
const o = document.createElement('option');
o.value = m.id_mengajar; o.textContent = m.kelas; sel.appendChild(o);
});
if (mengajars.length === 1) sel.value = mengajars[0].id_mengajar;
document.querySelector('#modalTugas input[name="judul_tugas"]').value = '';
document.querySelector('#modalTugas textarea[name="keterangan"]').value = '';
document.getElementById('deadlineDate').value = '';
document.getElementById('deadlineTime').value = '';
document.getElementById('deadlineCombined').value = '';
document.getElementById('tugasPreview').classList.remove('show');
document.getElementById('tugasFile').value = '';
new bootstrap.Modal(document.getElementById('modalTugas')).show();
}
document.getElementById('formBuatTugas').addEventListener('submit', function(e) {
const date = document.getElementById('deadlineDate').value;
const time = document.getElementById('deadlineTime').value;
if (!date || !time) {
e.preventDefault();
alert('Mohon isi tanggal dan jam deadline.');
return;
}
document.getElementById('deadlineCombined').value = date + ' ' + time + ':00';
});
function previewFile(input, previewId, nameId) {
const preview = document.getElementById(previewId);
const nameEl = document.getElementById(nameId);
if (input.files && input.files[0]) {
const file = input.files[0];
if (file.size > 10 * 1024 * 1024) {
alert('❌ Ukuran file melebihi 10MB.');
input.value = '';
preview.classList.remove('show');
return;
}
nameEl.textContent = file.name + ' (' + (file.size / 1024 / 1024).toFixed(2) + ' MB)';
preview.classList.add('show');
}
}
</script>
@endpush