MIF_E31230356/resources/views/siswa/challenge/kerjakan.blade.php

406 lines
10 KiB
PHP

@extends('siswa.layouts.app')
@section('title', 'Kerjakan Challenge')
@push('styles')
<style>
/* Sembunyikan sidebar saat kerjakan biar fokus */
.siswa-wrapper .sidebar { display: none !important; }
.sidebar-toggle-btn { display: none !important; }
.quiz-wrapper {
max-width: 680px;
margin: 0 auto;
padding: 10px 0 40px;
}
.quiz-header {
text-align: center;
margin-bottom: 28px;
}
.quiz-title {
font-size: 20px;
font-weight: 800;
color: #1e293b;
margin-bottom: 6px;
}
.quiz-meta {
font-size: 13px;
color: #64748b;
display: flex;
justify-content: center;
gap: 16px;
flex-wrap: wrap;
}
.quiz-meta span {
display: inline-flex;
align-items: center;
gap: 4px;
}
/* Progress bar */
.progress-bar-wrap {
background: #e2e8f0;
border-radius: 99px;
height: 8px;
margin-bottom: 28px;
overflow: hidden;
}
.progress-bar-fill {
height: 100%;
background: linear-gradient(90deg, #667eea, #764ba2);
border-radius: 99px;
transition: width 0.4s ease;
}
.progress-label {
text-align: center;
font-size: 12px;
color: #64748b;
font-weight: 600;
margin-bottom: 8px;
}
/* Soal card */
.soal-card {
background: white;
border-radius: 20px;
border: 2px solid #e5e5e5;
padding: 28px;
margin-bottom: 20px;
display: none; /* sembunyikan semua dulu */
}
.soal-card.active { display: block; }
.soal-number {
display: inline-block;
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
font-size: 12px;
font-weight: 700;
padding: 3px 12px;
border-radius: 99px;
margin-bottom: 14px;
}
.soal-pertanyaan {
font-size: 16px;
font-weight: 600;
color: #1e293b;
margin-bottom: 20px;
line-height: 1.7;
}
/* Opsi pilihan */
.opsi-list { display: flex; flex-direction: column; gap: 10px; }
.opsi-item {
display: flex;
align-items: center;
gap: 14px;
background: #f8fafc;
border: 2px solid #e2e8f0;
border-radius: 12px;
padding: 13px 16px;
cursor: pointer;
transition: all 0.18s;
font-size: 14px;
color: #1e293b;
user-select: none;
}
.opsi-item:hover {
border-color: #667eea;
background: #f0eeff;
}
.opsi-item.selected {
border-color: #667eea;
background: linear-gradient(135deg, #ede9fe, #f5f3ff);
font-weight: 600;
color: #4c1d95;
}
.opsi-item input[type="radio"] { display: none; }
.opsi-label-circle {
width: 32px;
height: 32px;
border-radius: 50%;
background: #e2e8f0;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 13px;
flex-shrink: 0;
transition: all 0.18s;
}
.opsi-item.selected .opsi-label-circle {
background: #667eea;
color: white;
}
/* Navigasi */
.nav-buttons {
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
}
.btn-nav {
padding: 11px 24px;
border-radius: 12px;
border: none;
font-size: 14px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
font-family: 'Poppins', sans-serif;
}
.btn-prev {
background: #f1f5f9;
color: #475569;
}
.btn-prev:hover { background: #e2e8f0; }
.btn-prev:disabled { opacity: 0.4; cursor: not-allowed; }
.btn-next {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
margin-left: auto;
}
.btn-next:hover { opacity: 0.9; }
.btn-submit {
background: linear-gradient(135deg, #22c55e, #16a34a);
color: white;
margin-left: auto;
display: none;
}
.btn-submit:hover { opacity: 0.9; }
/* Nomor soal dots */
.soal-dots {
display: flex;
justify-content: center;
gap: 8px;
margin-bottom: 20px;
flex-wrap: wrap;
}
.soal-dot {
width: 32px;
height: 32px;
border-radius: 50%;
background: #e2e8f0;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: 700;
color: #64748b;
cursor: pointer;
transition: all 0.2s;
}
.soal-dot.active { background: #667eea; color: white; }
.soal-dot.answered { background: #dcfce7; color: #16a34a; border: 2px solid #22c55e; }
.soal-dot.active.answered { background: #22c55e; color: white; }
/* Warning belum semua dijawab */
.warning-box {
background: #fff7ed;
border: 1px solid #fed7aa;
border-radius: 12px;
padding: 12px 16px;
font-size: 13px;
color: #c2410c;
font-weight: 500;
margin-bottom: 16px;
display: none;
}
</style>
@endpush
@section('content')
<div class="quiz-wrapper">
{{-- Header --}}
<div class="quiz-header">
<div class="quiz-title">🏆 {{ $challenge->judul_challenge }}</div>
<div class="quiz-meta">
<span>📝 {{ $challenge->soal->count() }} Soal</span>
<span> {{ $challenge->exp }} EXP</span>
<span> Tenggat: {{ \Carbon\Carbon::parse($challenge->tenggat_waktu)->format('d M Y, H:i') }}</span>
</div>
</div>
{{-- Dots navigasi soal --}}
<div class="soal-dots" id="soalDots">
@foreach($challenge->soal as $i => $soal)
<div class="soal-dot {{ $i === 0 ? 'active' : '' }}"
id="dot-{{ $i }}"
onclick="goToSoal({{ $i }})">
{{ $i + 1 }}
</div>
@endforeach
</div>
{{-- Progress --}}
<div class="progress-label" id="progressLabel">Soal 1 dari {{ $challenge->soal->count() }}</div>
<div class="progress-bar-wrap">
<div class="progress-bar-fill" id="progressBar"
style="width: {{ round(1 / $challenge->soal->count() * 100) }}%"></div>
</div>
{{-- Form --}}
<form action="{{ route('siswa.challenge.submit', $challenge->id_challenge) }}"
method="POST" id="quizForm">
@csrf
{{-- Soal --}}
@foreach($challenge->soal as $i => $soal)
<div class="soal-card {{ $i === 0 ? 'active' : '' }}" id="soal-{{ $i }}">
<span class="soal-number">Soal {{ $i + 1 }}</span>
<p class="soal-pertanyaan">{{ $soal->pertanyaan }}</p>
<div class="opsi-list">
@foreach(['A','B','C','D'] as $opsi)
@php $key = 'opsi_' . strtolower($opsi); @endphp
<label class="opsi-item" id="label-{{ $i }}-{{ $opsi }}"
onclick="pilihJawaban({{ $i }}, '{{ $opsi }}', {{ $soal->id_soal }})">
<input type="radio" name="jawaban[{{ $soal->id_soal }}]"
value="{{ $opsi }}" id="radio-{{ $i }}-{{ $opsi }}">
<span class="opsi-label-circle">{{ $opsi }}</span>
<span>{{ $soal->$key }}</span>
</label>
@endforeach
</div>
</div>
@endforeach
{{-- Warning --}}
<div class="warning-box" id="warningBox">
⚠️ Masih ada <span id="warningCount"></span> soal yang belum dijawab. Yakin ingin submit?
</div>
{{-- Navigasi --}}
<div class="nav-buttons">
<button type="button" class="btn-nav btn-prev" id="btnPrev"
onclick="prevSoal()" disabled> Sebelumnya</button>
<button type="button" class="btn-nav btn-next" id="btnNext"
onclick="nextSoal()">Selanjutnya </button>
<button type="submit" class="btn-nav btn-submit" id="btnSubmit"
onclick="return konfirmasiSubmit()">
🎯 Selesai & Submit
</button>
</div>
</form>
</div>
@endsection
@push('scripts')
<script>
const totalSoal = {{ $challenge->soal->count() }};
let currentSoal = 0;
let jawaban = {}; // { index: 'A'/'B'/'C'/'D' }
function goToSoal(index) {
// Sembunyikan soal sekarang
document.getElementById(`soal-${currentSoal}`).classList.remove('active');
document.getElementById(`dot-${currentSoal}`).classList.remove('active');
// Tampilkan soal target
currentSoal = index;
document.getElementById(`soal-${currentSoal}`).classList.add('active');
const dot = document.getElementById(`dot-${currentSoal}`);
dot.classList.add('active');
updateNav();
updateProgress();
}
function nextSoal() {
if (currentSoal < totalSoal - 1) goToSoal(currentSoal + 1);
}
function prevSoal() {
if (currentSoal > 0) goToSoal(currentSoal - 1);
}
function pilihJawaban(soalIndex, opsi, idSoal) {
jawaban[soalIndex] = opsi;
// Hapus selected dari semua opsi soal ini
['A','B','C','D'].forEach(o => {
document.getElementById(`label-${soalIndex}-${o}`)?.classList.remove('selected');
});
// Tandai yang dipilih
document.getElementById(`label-${soalIndex}-${opsi}`)?.classList.add('selected');
document.getElementById(`radio-${soalIndex}-${opsi}`).checked = true;
// Update dot
const dot = document.getElementById(`dot-${soalIndex}`);
dot.classList.add('answered');
updateProgress();
}
function updateNav() {
const btnPrev = document.getElementById('btnPrev');
const btnNext = document.getElementById('btnNext');
const btnSubmit = document.getElementById('btnSubmit');
btnPrev.disabled = currentSoal === 0;
if (currentSoal === totalSoal - 1) {
btnNext.style.display = 'none';
btnSubmit.style.display = 'block';
} else {
btnNext.style.display = 'block';
btnSubmit.style.display = 'none';
}
}
function updateProgress() {
const answered = Object.keys(jawaban).length;
const pct = Math.round(((currentSoal + 1) / totalSoal) * 100);
document.getElementById('progressBar').style.width = pct + '%';
document.getElementById('progressLabel').textContent =
`Soal ${currentSoal + 1} dari ${totalSoal} · ${answered} terjawab`;
}
function konfirmasiSubmit() {
const belum = totalSoal - Object.keys(jawaban).length;
const warningBox = document.getElementById('warningBox');
if (belum > 0) {
document.getElementById('warningCount').textContent = belum + ' soal';
warningBox.style.display = 'block';
return confirm(`Masih ada ${belum} soal yang belum dijawab. Yakin ingin submit?`);
}
return confirm('Yakin ingin submit jawaban? Jawaban tidak bisa diubah setelah submit.');
}
// Init
updateNav();
updateProgress();
</script>
@endpush