MIF_E31230356/resources/views/siswa/tugas/show.blade.php

696 lines
22 KiB
PHP

@extends('siswa.layouts.app')
@section('title', $tugas->judul_tugas)
@push('styles')
<style>
.back-link {
display: inline-flex;
align-items: center;
gap: 8px;
color: #2b8ef3;
font-weight: 600;
font-size: 14px;
text-decoration: none;
margin-bottom: 20px;
}
.back-link:hover { text-decoration: underline; }
.tugas-header {
background: #fff;
border-radius: 20px;
padding: 28px;
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
margin-bottom: 20px;
border-left: 5px solid #2b8ef3;
}
.tugas-header.terlambat { border-left-color: #ef4444; }
.tugas-header.selesai { border-left-color: #22c55e; }
.tugas-judul {
font-size: 20px;
font-weight: 700;
color: #1e293b;
margin: 0 0 12px;
}
.tugas-meta-row {
display: flex;
flex-wrap: wrap;
gap: 16px;
margin-bottom: 16px;
}
.meta-chip {
display: inline-flex;
align-items: center;
gap: 6px;
background: #f1f5f9;
color: #475569;
font-size: 13px;
font-weight: 500;
padding: 6px 12px;
border-radius: 99px;
}
.meta-chip.deadline-chip {
background: #fee2e2;
color: #ef4444;
}
.meta-chip.deadline-chip.aman {
background: #e6f0ff;
color: #2b8ef3;
}
.keterangan-box {
background: #f8fafc;
border-radius: 12px;
padding: 16px;
font-size: 14px;
color: #475569;
line-height: 1.7;
border: 1px solid #e2e8f0;
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;
border-radius: 20px;
padding: 28px;
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
margin-bottom: 20px;
}
.submit-title {
font-size: 17px;
font-weight: 700;
color: #1e293b;
margin: 0 0 20px;
display: flex;
align-items: center;
gap: 8px;
}
.upload-area {
border: 2px dashed #cbd5e1;
border-radius: 14px;
padding: 32px;
text-align: center;
cursor: pointer;
transition: border-color 0.2s, background 0.2s;
position: relative;
}
.upload-area:hover, .upload-area.drag-over {
border-color: #2b8ef3;
background: #f0f7ff;
}
.upload-area input[type="file"] {
position: absolute;
inset: 0;
opacity: 0;
cursor: pointer;
width: 100%;
height: 100%;
}
.upload-icon {
margin-bottom: 10px;
display: flex;
justify-content: center;
}
.upload-text { font-size: 14px; color: #64748b; margin: 0 0 4px; }
.upload-hint { font-size: 12px; color: #94a3b8; margin: 0; }
.file-preview {
display: none;
align-items: center;
gap: 12px;
background: #f0f7ff;
border-radius: 10px;
padding: 12px 16px;
margin-top: 12px;
}
.file-preview.show { display: flex; }
.file-preview-name { flex: 1; font-size: 14px; font-weight: 600; color: #1e293b; }
.file-preview-size { font-size: 12px; color: #94a3b8; }
.btn-submit {
width: 100%;
background: #2b8ef3;
color: white;
border: none;
border-radius: 12px;
padding: 14px;
font-size: 15px;
font-weight: 700;
cursor: pointer;
margin-top: 16px;
transition: background 0.2s;
}
.btn-submit:hover { background: #1a7ae0; }
.btn-submit:disabled { background: #cbd5e1; cursor: not-allowed; }
/* SUDAH KUMPUL */
.sudah-kumpul-card {
background: #dcfce7;
border-radius: 20px;
padding: 28px;
text-align: center;
margin-bottom: 20px;
}
.sudah-kumpul-icon { margin-bottom: 10px; display: flex; justify-content: center; }
.sudah-kumpul-title { font-size: 17px; font-weight: 700; color: #166534; margin: 0 0 8px; }
.sudah-kumpul-sub { font-size: 14px; color: #16a34a; margin: 0; }
.terlambat-warning {
background: #fff7ed;
border: 1px solid #fed7aa;
border-radius: 14px;
padding: 16px 20px;
display: flex;
gap: 12px;
align-items: flex-start;
margin-bottom: 20px;
font-size: 13px;
color: #9a3412;
}
.terlambat-warning-icon { display: flex; align-items: center; flex-shrink: 0; }
.alert-success {
background: #dcfce7;
color: #166534;
border-radius: 12px;
padding: 14px 18px;
margin-bottom: 20px;
font-weight: 500;
font-size: 14px;
display: flex;
align-items: center;
gap: 8px;
}
.alert-error {
background: #fee2e2;
color: #991b1b;
border-radius: 12px;
padding: 14px 18px;
margin-bottom: 20px;
font-weight: 500;
font-size: 14px;
display: flex;
align-items: center;
gap: 8px;
}
/* GANTI FILE */
.btn-ganti-file {
display: inline-flex;
align-items: center;
gap: 6px;
margin-top: 10px;
background: #fff7ed;
color: #f97316;
padding: 8px 18px;
border-radius: 10px;
font-weight: 600;
font-size: 13px;
border: none;
cursor: pointer;
transition: background 0.2s;
}
.btn-ganti-file:hover { background: #fed7aa; }
.ganti-file-box {
display: none;
margin-top: 16px;
background: #fff;
border-radius: 14px;
padding: 20px;
text-align: left;
border: 1px solid #e2e8f0;
}
.ganti-file-title {
font-weight: 700;
color: #1e293b;
margin: 0 0 12px;
font-size: 15px;
display: flex;
align-items: center;
gap: 6px;
}
.btn-batal-ganti {
flex: 1;
background: #f1f5f9;
color: #64748b;
border: none;
border-radius: 10px;
padding: 12px;
font-weight: 600;
font-size: 14px;
cursor: pointer;
transition: background 0.2s;
}
.btn-batal-ganti:hover { background: #e2e8f0; }
.btn-simpan-ganti {
flex: 2;
background: #f97316;
color: white;
border: none;
border-radius: 10px;
padding: 12px;
font-weight: 700;
font-size: 14px;
cursor: pointer;
transition: background 0.2s;
}
.btn-simpan-ganti:hover { background: #ea6c0a; }
.btn-simpan-ganti:disabled { background: #cbd5e1; cursor: not-allowed; }
</style>
@endpush
@section('content')
<a href="{{ route('siswa.tugas.index') }}" class="back-link"> Kembali ke Daftar Tugas</a>
@if(session('success'))
<div class="alert-success">
<img src="{{ asset('images/icon/siswat/v.png') }}" alt="Berhasil" class="icon-sm">
{{ session('success') }}
</div>
@endif
@if(session('error'))
<div class="alert-error">
<img src="{{ asset('images/icon/siswat/x.png') }}" alt="Gagal" class="icon-sm">
{{ session('error') }}
</div>
@endif
{{-- DETAIL TUGAS --}}
@php
$headerClass = $sudahKumpul ? 'selesai' : ($terlambat ? 'terlambat' : '');
$deadlineClass = $terlambat ? '' : 'aman';
@endphp
<div class="tugas-header {{ $headerClass }}">
<h1 class="tugas-judul">{{ $tugas->judul_tugas }}</h1>
<div class="tugas-meta-row">
<span class="meta-chip">
<img src="{{ asset('images/icon/siswat/stacked.png') }}" alt="Mata pelajaran" class="icon-sm">
{{ optional(optional($tugas->mengajar)->mapel)->nama_mapel ?? '-' }}
</span>
<span class="meta-chip">
<img src="{{ asset('images/icon/siswat/guru.png') }}" alt="Guru" class="icon-sm">
{{ optional(optional($tugas->mengajar)->guru)->nama ?? '-' }}
</span>
<span class="meta-chip deadline-chip {{ $deadlineClass }}">
<img src="{{ asset('images/icon/siswat/alarm.png') }}" alt="Deadline" class="icon-sm">
Deadline: {{ \Carbon\Carbon::parse($tugas->deadline)->format('d M Y, H:i') }}
</span>
</div>
@if($tugas->keterangan)
<div class="keterangan-box">
{!! nl2br(e($tugas->keterangan)) !!}
</div>
@endif
</div>
{{-- WARNING TERLAMBAT --}}
@if($terlambat && !$sudahKumpul)
<div class="terlambat-warning">
<span class="terlambat-warning-icon">
<img src="{{ asset('images/icon/siswat/alert.png') }}" alt="Peringatan terlambat" class="icon-md">
</span>
<div>
<strong>Deadline sudah lewat!</strong><br>
Kamu masih bisa mengumpulkan tugas ini, tapi akan ditandai sebagai <strong>terlambat</strong>.
</div>
</div>
@endif
{{-- SUDAH DIKUMPULKAN --}}
@if($sudahKumpul)
<div class="sudah-kumpul-card">
<div class="sudah-kumpul-icon">
<img src="{{ asset('images/icon/siswat/confetti.png') }}" alt="Tugas sudah dikumpulkan" class="icon-mascot" style="width:80px;margin-top:0;">
</div>
<p class="sudah-kumpul-title">Tugas sudah dikumpulkan!</p>
<p class="sudah-kumpul-sub">
Dikumpulkan pada {{ \Carbon\Carbon::parse($pengumpulan->tanggal_submit)->format('d M Y, H:i') }}
&bull; Status: <strong>{{ ucfirst($pengumpulan->status) }}</strong>
</p>
@if($pengumpulan->lampiran_tugas)
<a href="{{ url('storage/app/public/' . $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;">
<img src="{{ asset('images/icon/gurud/link.png') }}" alt="Lampiran" class="icon-md">
Lihat File yang Dikumpulkan
</a>
@endif
{{-- Tombol ganti file hanya muncul kalau belum melewati deadline --}}
@if(!$terlambat)
<br>
<button class="btn-ganti-file" onclick="toggleGantiFile()">
<img src="{{ asset('images/icon/siswat/upload.png') }}" alt="Ganti file" class="icon-sm">
Ganti File
</button>
<div class="ganti-file-box" id="gantiFileBox">
<p class="ganti-file-title">
<img src="{{ asset('images/icon/siswat/upload.png') }}" alt="Upload" class="icon-md">
Ganti File Jawaban
</p>
@if(session('error_ganti'))
<div class="alert-error" style="margin-bottom:12px">
<img src="{{ asset('images/icon/siswat/x.png') }}" alt="Error" class="icon-sm">
{{ session('error_ganti') }}
</div>
@endif
<form action="{{ route('siswa.tugas.gantiFile', $tugas->id_tugas) }}"
method="POST"
enctype="multipart/form-data">
@csrf
@method('PUT')
@error('lampiran_tugas')
<div class="alert-error" style="margin-bottom:12px">
<img src="{{ asset('images/icon/siswat/x.png') }}" alt="Error" class="icon-sm">
{{ $message }}
</div>
@enderror
<div class="upload-area" id="uploadAreaGanti">
<input type="file"
name="lampiran_tugas"
id="fileInputGanti"
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:40px;margin-top:0;">
</div>
<p class="upload-text"><strong>Klik untuk pilih file baru</strong> atau drag & drop</p>
<p class="upload-hint">PDF, DOC, DOCX, JPG, PNG &bull; Maks. 5MB</p>
</div>
<div class="file-preview" id="filePreviewGanti">
<img src="{{ asset('images/icon/siswat/buku1.png') }}" alt="File terpilih" class="icon-md">
<span class="file-preview-name" id="fileNameGanti">-</span>
<span class="file-preview-size" id="fileSizeGanti">-</span>
</div>
<div style="display:flex;gap:10px;margin-top:12px;">
<button type="button" class="btn-batal-ganti" onclick="toggleGantiFile()">
Batal
</button>
<button type="submit" class="btn-simpan-ganti" id="submitBtnGanti" disabled>
Simpan File Baru
</button>
</div>
</form>
</div>
@else
<p style="font-size:12px;color:#94a3b8;margin-top:10px;">
Deadline sudah lewat, file tidak dapat diganti.
</p>
@endif
</div>
@else
{{-- GRID: LAMPIRAN GURU (kiri) + UPLOAD SISWA (kanan) --}}
<div class="tugas-bottom-grid">
{{-- 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>
@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>
<a href="{{ url('storage/app/public/' . $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>
@endif
</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>
</div>
@endif
@endsection
@push('scripts')
<script>
// ===== Upload pertama kali =====
const fileInput = document.getElementById('fileInput');
const filePreview = document.getElementById('filePreview');
const fileName = document.getElementById('fileName');
const fileSize = document.getElementById('fileSize');
const submitBtn = document.getElementById('submitBtn');
const uploadArea = document.getElementById('uploadArea');
if (fileInput) {
fileInput.addEventListener('change', function () {
if (this.files && this.files[0]) {
const file = this.files[0];
fileName.textContent = file.name;
fileSize.textContent = (file.size / 1024 / 1024).toFixed(2) + ' MB';
filePreview.classList.add('show');
submitBtn.disabled = false;
}
});
uploadArea.addEventListener('dragover', (e) => {
e.preventDefault();
uploadArea.classList.add('drag-over');
});
uploadArea.addEventListener('dragleave', () => {
uploadArea.classList.remove('drag-over');
});
uploadArea.addEventListener('drop', (e) => {
e.preventDefault();
uploadArea.classList.remove('drag-over');
if (e.dataTransfer.files[0]) {
fileInput.files = e.dataTransfer.files;
fileInput.dispatchEvent(new Event('change'));
}
});
}
// ===== Ganti file =====
function toggleGantiFile() {
const box = document.getElementById('gantiFileBox');
box.style.display = box.style.display === 'none' || box.style.display === '' ? 'block' : 'none';
}
const fileInputGanti = document.getElementById('fileInputGanti');
const filePreviewGanti = document.getElementById('filePreviewGanti');
const fileNameGanti = document.getElementById('fileNameGanti');
const fileSizeGanti = document.getElementById('fileSizeGanti');
const submitBtnGanti = document.getElementById('submitBtnGanti');
if (fileInputGanti) {
fileInputGanti.addEventListener('change', function () {
if (this.files && this.files[0]) {
const file = this.files[0];
fileNameGanti.textContent = file.name;
fileSizeGanti.textContent = (file.size / 1024 / 1024).toFixed(2) + ' MB';
filePreviewGanti.classList.add('show');
submitBtnGanti.disabled = false;
}
});
}
// Buka otomatis form ganti file jika ada error validasi dari ganti file
@if(session('error_ganti') || ($errors->any() && old('_method') === 'PUT'))
document.addEventListener('DOMContentLoaded', function() {
const box = document.getElementById('gantiFileBox');
if (box) box.style.display = 'block';
});
@endif
</script>
@endpush