508 lines
19 KiB
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 |