untitled

Pasted Sep 30, 2026, 11:29 PM1 file754 lines

Scan to open on your phone

Point a camera at the QR code - it opens this exact paste, no app needed.

https://codepastes.com/zzgt6r2cgvjpyr4n
untitled
<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Kuis & Pembelajaran Matematika Kelas 7 SMP</title>
    <style>
        * {
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 0;
            padding: 0;
        }

        body {
            background-color: #f0f4f8;
            color: #333;
            padding: 20px;
        }

        .container {
            max-width: 900px;
            margin: 0 auto;
            background: #ffffff;
            padding: 25px;
            border-radius: 12px;
            box-shadow: 0 4px 15px rgba(0,0,0,0.1);
        }

        h1, h2, h3 {
            color: #1e3a8a;
            margin-bottom: 15px;
            text-align: center;
        }

        .nav-menu {
            display: flex;
            justify-content: center;
            gap: 10px;
            flex-wrap: wrap;
            margin-bottom: 25px;
            border-bottom: 2px solid #e2e8f0;
            padding-bottom: 15px;
        }

        button.btn-nav {
            background-color: #3b82f6;
            color: white;
            border: none;
            padding: 10px 18px;
            border-radius: 8px;
            cursor: pointer;
            font-weight: bold;
            transition: background 0.2s;
        }

        button.btn-nav:hover {
            background-color: #1d4ed8;
        }

        .section {
            display: none;
        }

        .section.active {
            display: block;
        }

        /* Form Profil */
        .form-group {
            margin-bottom: 15px;
        }

        label {
            display: block;
            font-weight: bold;
            margin-bottom: 5px;
        }

        input[type="text"], select {
            width: 100%;
            padding: 10px;
            border: 1px solid #cbd5e1;
            border-radius: 6px;
            font-size: 16px;
        }

        .btn-submit {
            background-color: #10b981;
            color: white;
            padding: 12px 20px;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            width: 100%;
            font-size: 16px;
            font-weight: bold;
        }

        .btn-submit:hover {
            background-color: #059669;
        }

        /* Tampilan Soal & Opsi */
        .card-soal {
            background: #f8fafc;
            border: 1px solid #e2e8f0;
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
        }

        .opsi-container {
            display: flex;
            flex-direction: column;
            gap: 10px;
            margin-top: 15px;
        }

        .btn-opsi {
            background-color: #ffffff;
            border: 2px solid #cbd5e1;
            padding: 12px;
            border-radius: 8px;
            text-align: left;
            cursor: pointer;
            font-size: 16px;
            transition: all 0.2s;
        }

        .btn-opsi:hover {
            background-color: #f1f5f9;
        }

        .btn-opsi.benar {
            background-color: #22c55e !important;
            color: white;
            border-color: #16a34a;
        }

        .btn-opsi.salah {
            background-color: #ef4444 !important;
            color: white;
            border-color: #dc2626;
        }

        .pembahasan {
            margin-top: 15px;
            padding: 12px;
            background-color: #e0f2fe;
            border-left: 4px solid #0284c7;
            border-radius: 4px;
            display: none;
        }

        /* Status Mini Game & Waktu */
        .status-bar {
            display: flex;
            justify-content: space-between;
            font-size: 18px;
            font-weight: bold;
            margin-bottom: 15px;
            background: #f1f5f9;
            padding: 10px 15px;
            border-radius: 8px;
        }

        .energi {
            color: #ef4444;
        }

        .timer {
            color: #d97706;
        }

        /* Tabel Leaderboard */
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 15px;
        }

        th, td {
            border: 1px solid #cbd5e1;
            padding: 12px;
            text-align: center;
        }

        th {
            background-color: #1e3a8a;
            color: white;
        }

        /* Ringkasan Materi */
        .materi-item {
            margin-bottom: 20px;
            border-bottom: 1px solid #e2e8f0;
            padding-bottom: 15px;
        }

        .materi-item h3 {
            text-align: left;
            color: #2563eb;
        }

        .contoh-soal {
            background: #f8fafc;
            padding: 10px;
            border-left: 3px solid #3b82f6;
            margin-top: 8px;
        }
    </style>
</head>
<body>

<div class="container">
    <h1>Aplikasi Matematika Kelas 7 SMP</h1>

    <!-- Identitas Siswa Terpasang -->
    <div id="profil-info" style="text-align: center; font-weight: bold; margin-bottom: 15px; color: #475569;">
        Status: <span id="nama-display" style="color:#2563eb;">Belum mengisi nama</span> | 
        Kelas: <span id="kelas-display" style="color:#2563eb;">-</span>
    </div>

    <!-- Navigasi -->
    <div class="nav-menu">
        <button class="btn-nav" onclick="bukaSection('sec-profil')">Profil Siswa</button>
        <button class="btn-nav" onclick="bukaSection('sec-materi')">Materi Lengkap</button>
        <button class="btn-nav" onclick="bukaSection('sec-latihan')">Latihan Soal</button>
        <button class="btn-nav" onclick="mulaiMinigame()">Mini Game (5 Energi)</button>
        <button class="btn-nav" onclick="mulaiSimulasiUTS()">Simulasi UTS (150 Mnt)</button>
        <button class="btn-nav" onclick="bukaSection('sec-leaderboard')">Leaderboard</button>
    </div>

    <!-- SECTION PROFIL -->
    <div id="sec-profil" class="section active">
        <h2>Identitas Siswa</h2>
        <form id="form-profil" onsubmit="simpanProfil(event)">
            <div class="form-group">
                <label for="nama">Nama Lengkap:</label>
                <input type="text" id="nama" required placeholder="Masukkan nama Anda">
            </div>
            <div class="form-group">
                <label for="kelas">Kelas:</label>
                <select id="kelas" required>
                    <option value="">-- Pilih Kelas --</option>
                    <option value="7A">7A</option>
                    <option value="7B">7B</option>
                    <option value="7C">7C</option>
                    <option value="7D">7D</option>
                    <option value="7E">7E</option>
                    <option value="7F">7F</option>
                    <option value="7G">7G</option>
                    <option value="7H">7H</option>
                    <option value="7I">7I</option>
                </select>
            </div>
            <button type="submit" class="btn-submit">Simpan & Mulai</button>
        </form>
    </div>

    <!-- SECTION MATERI LENGKAP -->
    <div id="sec-materi" class="section">
        <h2>Materi Ringkas & Cara Penyelesaian</h2>

        <div class="materi-item">
            <h3>1. Pengertian & Garis Bilangan Bulat</h3>
            <p>Bilangan bulat terdiri dari bilangan positif (1, 2, 3, ...), nol (0), dan negatif (-1, -2, -3, ...). Pada garis bilangan, semakin ke kanan posisinya maka nilainya semakin besar, dan semakin ke kiri posisinya nilainya semakin kecil.</p>
        </div>

        <div class="materi-item">
            <h3>2. Operasi Hitung Bilangan Bulat</h3>
            <p><strong>Penjumlahan/Pengurangan:</strong> Jika tanda sama (keduanya positif atau negatif), jumlahkan angkanya. Jika tanda berbeda, kurangkan angka besar dengan angka kecil dan gunakan tanda dari angka yang lebih besar.</p>
            <p><strong>Perkalian/Pembagian:</strong> Positif &times; Positif = Positif, Negatif &times; Negatif = Positif, Positif &times; Negatif = Negatif.</p>
            <div class="contoh-soal">
                <strong>Contoh:</strong> Hitung (-8) + 12 - (-5)<br>
                <strong>Penyelesaian:</strong> (-8) + 12 + 5 = 4 + 5 = 9.
            </div>
        </div>

        <div class="materi-item">
            <h3>3. FPB dan KPK</h3>
            <p><strong>FPB (Faktor Persekutuan Terbesar):</strong> Perkalian faktor prima yang sama dengan pangkat terendah.</p>
            <p><strong>KPK (Kelipatan Persekutuan Terkecil):</strong> Perkalian semua faktor prima, jika ada yang sama ambil pangkat tertinggi.</p>
            <div class="contoh-soal">
                <strong>Contoh:</strong> Cari FPB dan KPK dari 12 (2² &times; 3) dan 18 (2 &times; 3²)<br>
                <strong>FPB:</strong> 2 &times; 3 = 6<br>
                <strong>KPK:</strong> 2² &times; 3² = 4 &times; 9 = 36
            </div>
        </div>

        <div class="materi-item">
            <h3>4. Pecahan & Desimal</h3>
            <p><strong>Mengubah Pecahan ke Desimal:</strong> Bagi pembilang dengan penyebut. Contoh: 3/4 = 3 &divide; 4 = 0,75.</p>
            <p><strong>Operasi Pecahan:</strong> Untuk penjumlahan/pengurangan, samakan penyebutnya terlebih dahulu menggunakan KPK penyebut.</p>
        </div>
    </div>

    <!-- SECTION LATIHAN SOAL -->
    <div id="sec-latihan" class="section">
        <h2>Latihan Soal (Tanpa Batas Waktu)</h2>
        <div id="container-latihan"></div>
    </div>

    <!-- SECTION MINI GAME -->
    <div id="sec-minigame" class="section">
        <h2>Mini Game Matematika</h2>
        <div class="status-bar">
            <span>Energi: <span id="display-energi" class="energi">❤️❤️❤️❤️❤️️</span></span>
            <span>Skor Game: <span id="skor-game">0</span></span>
        </div>
        <div id="container-minigame"></div>
    </div>

    <!-- SECTION SIMULASI UTS -->
    <div id="sec-uts" class="section">
        <h2>Simulasi UTS Matematika Kelas 7</h2>
        <div class="status-bar">
            <span>Waktu Tersisa: <span id="display-timer" class="timer">150:00</span></span>
            <span>Progres: <span id="progres-uts">Soal 1</span></span>
        </div>
        <div id="container-uts"></div>
        <button id="btn-selesai-uts" class="btn-submit" style="margin-top:15px;" onclick="selesaiUTS()">Kumpulkan Jawaban UTS</button>
    </div>

    <!-- SECTION LEADERBOARD -->
    <div id="sec-leaderboard" class="section">
        <h2>Leaderboard Real-Time Simulasi UTS</h2>
        <table>
            <thead>
                <tr>
                    <th>Peringkat</th>
                    <th>Nama</th>
                    <th>Kelas</th>
                    <th>Nilai UTS</th>
                    <th>Waktu Selesai</th>
                </tr>
            </thead>
            <tbody id="tbody-leaderboard">
                <!-- Data Leaderboard Muncul di Sini -->
            </tbody>
        </table>
    </div>
</div>

<script>
    // --- SOUND EFFECTS SYNTHESIZER (TANPA AUDIO EXTERNAL) ---
    const audioCtx = new (window.AudioContext || window.webkitAudioContext)();

    function mainkanSuaraBenar() {
        if (audioCtx.state === 'suspended') audioCtx.resume();
        const osc = audioCtx.createOscillator();
        const gain = audioCtx.createGain();
        osc.type = 'sine';
        osc.frequency.setValueAtTime(523.25, audioCtx.currentTime); // C5
        osc.frequency.exponentialRampToValueAtTime(659.25, audioCtx.currentTime + 0.1); // E5
        osc.frequency.exponentialRampToValueAtTime(783.99, audioCtx.currentTime + 0.2); // G5
        gain.gain.setValueAtTime(0.3, audioCtx.currentTime);
        gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.3);
        osc.connect(gain);
        gain.connect(audioCtx.destination);
        osc.start();
        osc.stop(audioCtx.currentTime + 0.3);
    }

    function mainkanSuaraSalah() {
        if (audioCtx.state === 'suspended') audioCtx.resume();
        const osc = audioCtx.createOscillator();
        const gain = audioCtx.createGain();
        osc.type = 'sawtooth';
        osc.frequency.setValueAtTime(220, audioCtx.currentTime); // A3
        osc.frequency.exponentialRampToValueAtTime(130.81, audioCtx.currentTime + 0.2); // C3
        gain.gain.setValueAtTime(0.3, audioCtx.currentTime);
        gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.3);
        osc.connect(gain);
        gain.connect(audioCtx.destination);
        osc.start();
        osc.stop(audioCtx.currentTime + 0.3);
    }

    // --- DATA SISWA & GLOBAL STATE ---
    let siswaAktiv = { nama: "", kelas: "" };
    let energiMinigame = 5;
    let skorMinigame = 0;
    let indexMinigame = 0;

    let timerUTS = null;
    let sisaWaktuUTS = 150 * 60; // 150 menit dalam detik
    let jawabanUTS = {};

    // --- BANK SOAL (BERBEDA UNTUK TIAP MODE) ---
    const soalLatihan = [
        {
            soal: "1. Suhu di Kota A adalah -4°C, sedangkan suhu di Kota B adalah 8°C. Berapakah selisih suhu kedua kota tersebut?",
            opsi: ["A. 4°C", "B. 12°C", "C. -12°C", "D. 8°C"],
            kunci: 1,
            pembahasan: "Selisih = Nilai Terbesar - Nilai Terkecil = 8 - (-4) = 8 + 4 = 12°C."
        },
        {
            soal: "2. Berapakah hasil dari (-15) + 20 × (-2)?",
            opsi: ["A. -55", "B. -10", "C. 25", "D. -25"],
            kunci: 0,
            pembahasan: "Kerjakan perkalian dulu: 20 × (-2) = -40. Lalu (-15) + (-40) = -55."
        },
        {
            soal: "3. Tentukan KPK dari bilangan 12 dan 18!",
            opsi: ["A. 6", "B. 24", "C. 36", "D. 72"],
            kunci: 2,
            pembahasan: "12 = 2² × 3, 18 = 2 × 3². KPK = 2² × 3² = 4 × 9 = 36."
        },
        {
            soal: "4. Bentuk desimal dari pecahan 3/8 adalah...",
            opsi: ["A. 0,375", "B. 0,625", "C. 0,380", "D. 0,830"],
            kunci: 0,
            pembahasan: "3 ÷ 8 = 0,375."
        },
        {
            soal: "5. Ibu membeli 2 1/2 kg beras dan 1 1/4 kg gula. Berapa kg total belanjaan Ibu?",
            opsi: ["A. 3 1/4 kg", "B. 3 3/4 kg", "C. 3 1/2 kg", "D. 4 kg"],
            kunci: 1,
            pembahasan: "2 1/2 + 1 1/4 = 5/2 + 5/4 = 10/4 + 5/4 = 15/4 = 3 3/4 kg."
        }
    ];

    const soalMinigame = [
        {
            soal: "Game Q1: Jika posisi awal kamu di titik -3 pada garis bilangan, lalu melangkah ke kanan 7 satuan, kamu berada di titik...",
            opsi: ["A. -10", "B. 4", "C. -4", "D. 10"],
            kunci: 1,
            pembahasan: "-3 + 7 = 4."
        },
        {
            soal: "Game Q2: FPB dari 24 dan 36 adalah...",
            opsi: ["A. 6", "B. 8", "C. 12", "D. 18"],
            kunci: 2,
            pembahasan: "24 = 2³ × 3, 36 = 2² × 3². FPB = 2² × 3 = 12."
        },
        {
            soal: "Game Q3: Hasil dari 3/5 + 0,4 adalah...",
            opsi: ["A. 0,8", "B. 1,0", "C. 0,7", "D. 1,2"],
            kunci: 1,
            pembahasan: "3/5 = 0,6. Maka 0,6 + 0,4 = 1,0."
        },
        {
            soal: "Game Q4: Hitunglah: (-5) × (-4) ÷ 2",
            opsi: ["A. -10", "B. 10", "C. -20", "D. 20"],
            kunci: 1,
            pembahasan: "(-5) × (-4) = 20. Lalu 20 ÷ 2 = 10."
        },
        {
            soal: "Game Q5: Sebuah tali panjangnya 5,5 meter dipotong menjadi beberapa bagian sepanjang 0,5 meter. Jumlah potongan tali adalah...",
            opsi: ["A. 10", "B. 11", "C. 12", "D. 9"],
            kunci: 1,
            pembahasan: "5,5 ÷ 0,5 = 11 potongan."
        }
    ];

    const soalUTS = [
        {
            soal: "1. Urutan bilangan bulat dari yang terkecil: -12, 5, -3, 0, 8, -1 adalah...",
            opsi: ["A. -12, -3, -1, 0, 5, 8", "B. 8, 5, 0, -1, -3, -12", "C. 0, -1, -3, -12, 5, 8", "D. -1, -3, -12, 0, 5, 8"],
            kunci: 0
        },
        {
            soal: "2. Hasil dari 48 ÷ (-6) + 12 × (-3) adalah...",
            opsi: ["A. -44", "B. -28", "C. 28", "D. 44"],
            kunci: 0
        },
        {
            soal: "3. Lampu A menyala setiap 8 detik, lampu B menyala setiap 12 detik. Kedua lampu menyala bersamaan setiap...",
            opsi: ["A. 16 detik", "B. 24 detik", "C. 36 detik", "D. 48 detik"],
            kunci: 1
        },
        {
            soal: "4. Nilai dari 5/6 - 1/3 + 1/4 adalah...",
            opsi: ["A. 3/4", "B. 1/2", "C. 2/3", "D. 7/12"],
            kunci: 0
        },
        {
            soal: "5. Pak Budi memiliki tanah seluas 1,2 hektar. Sebanyak 1/3 bagian ditanami padi. Sisa tanah Pak Budi adalah...",
            opsi: ["A. 0,4 hektar", "B. 0,6 hektar", "C. 0,8 hektar", "D. 0,9 hektar"],
            kunci: 2
        }
    ];

    // --- NAVIGASI AMPUH ---
    function bukaSection(idSection) {
        document.querySelectorAll('.section').forEach(sec => sec.classList.remove('active'));
        document.getElementById(idSection).classList.add('active');
        if (idSection === 'sec-leaderboard') muatLeaderboard();
    }

    // --- PROFIL SISWA ---
    function simpanProfil(e) {
        e.preventDefault();
        siswaAktiv.nama = document.getElementById('nama').value;
        siswaAktiv.kelas = document.getElementById('kelas').value;

        document.getElementById('nama-display').innerText = siswaAktiv.nama;
        document.getElementById('kelas-display').innerText = siswaAktiv.kelas;

        alert('Data berhasil disimpan! Silakan pilih menu di atas.');
        bukaSection('sec-latihan');
        tampilkanLatihan();
    }

    function validasiSiswa() {
        if (!siswaAktiv.nama || !siswaAktiv.kelas) {
            alert('Harap isi Nama dan Kelas pada menu Profil Siswa terlebih dahulu!');
            bukaSection('sec-profil');
            return false;
        }
        return true;
    }

    // --- MODE LATIHAN SOAL ---
    function tampilkanLatihan() {
        const container = document.getElementById('container-latihan');
        container.innerHTML = '';

        soalLatihan.forEach((item, index) => {
            const el = document.createElement('div');
            el.className = 'card-soal';
            el.innerHTML = `
                <p><strong>${item.soal}</strong></p>
                <div class="opsi-container">
                    ${item.opsi.map((ops, i) => `
                        <button class="btn-opsi" onclick="jawabLatihan(this, ${index}, ${i})">${ops}</button>
                    `).join('')}
                </div>
                <div id="pembahasan-latihan-${index}" class="pembahasan">
                    <strong>Pembahasan & Cara Penyelesaian:</strong><br>
                    ${item.pembahasan}
                </div>
            `;
            container.appendChild(el);
        });
    }

    function jawabLatihan(btn, indexSoal, opsiDipilih) {
        const parent = btn.parentElement;
        const tombolOpsi = parent.querySelectorAll('.btn-opsi');
        const kunci = soalLatihan[indexSoal].kunci;

        // Kunci tombol agar tidak diklik dua kali
        tombolOpsi.forEach(b => b.style.pointerEvents = 'none');

        if (opsiDipilih === kunci) {
            btn.classList.add('benar');
            mainkanSuaraBenar();
        } else {
            btn.classList.add('salah');
            tombolOpsi[kunci].classList.add('benar');
            mainkanSuaraSalah();
        }

        // Tampilkan pembahasan
        document.getElementById(`pembahasan-latihan-${indexSoal}`).style.display = 'block';
    }

    // --- MODE MINI GAME ---
    function mulaiMinigame() {
        if (!validasiSiswa()) return;

        energiMinigame = 5;
        skorMinigame = 0;
        indexMinigame = 0;
        updateDisplayMinigame();
        bukaSection('sec-minigame');
        tampilkanSoalMinigame();
    }

    function updateDisplayMinigame() {
        document.getElementById('display-energi').innerText = '❤️'.repeat(energiMinigame);
        document.getElementById('skor-game').innerText = skorMinigame;
    }

    function tampilkanSoalMinigame() {
        const container = document.getElementById('container-minigame');
        if (indexMinigame >= soalMinigame.length) {
            container.innerHTML = `<h3>🎉 Selamat! Anda Menyelesaikan Mini Game!</h3><p>Skor Akhir: ${skorMinigame}</p>`;
            return;
        }

        const item = soalMinigame[indexMinigame];
        container.innerHTML = `
            <div class="card-soal">
                <p><strong>${item.soal}</strong></p>
                <div class="opsi-container">
                    ${item.opsi.map((ops, i) => `
                        <button class="btn-opsi" onclick="jawabMinigame(this, ${i})">${ops}</button>
                    `).join('')}
                </div>
                <div id="pembahasan-minigame" class="pembahasan">
                    <strong>Pembahasan:</strong><br>${item.pembahasan}
                </div>
                <button id="btn-next-game" class="btn-submit" style="display:none; margin-top:15px;" onclick="lanjutMinigame()">Soal Berikutnya</button>
            </div>
        `;
    }

    function jawabMinigame(btn, opsiDipilih) {
        const parent = btn.parentElement;
        const tombolOpsi = parent.querySelectorAll('.btn-opsi');
        const kunci = soalMinigame[indexMinigame].kunci;

        tombolOpsi.forEach(b => b.style.pointerEvents = 'none');

        if (opsiDipilih === kunci) {
            btn.classList.add('benar');
            mainkanSuaraBenar();
            skorMinigame += 20;
        } else {
            btn.classList.add('salah');
            tombolOpsi[kunci].classList.add('benar');
            mainkanSuaraSalah();
            energiMinigame--;
        }

        updateDisplayMinigame();
        document.getElementById('pembahasan-minigame').style.display = 'block';

        if (energiMinigame <= 0) {
            setTimeout(() => {
                alert('💥 Energi Anda Habis! Game Over!');
                document.getElementById('container-minigame').innerHTML = `<h3>Game Over!</h3><p>Skor Anda: ${skorMinigame}</p>`;
            }, 500);
        } else {
            document.getElementById('btn-next-game').style.display = 'block';
        }
    }

    function lanjutMinigame() {
        indexMinigame++;
        tampilkanSoalMinigame();
    }

    // --- MODE SIMULASI UTS ---
    function mulaiSimulasiUTS() {
        if (!validasiSiswa()) return;

        jawabanUTS = {};
        sisaWaktuUTS = 150 * 60; // 150 menit
        bukaSection('sec-uts');
        tampilkanSoalUTS();

        if (timerUTS) clearInterval(timerUTS);
        timerUTS = setInterval(updateTimerUTS, 1000);
    }

    function updateTimerUTS() {
        const menit = Math.floor(sisaWaktuUTS / 60);
        const detik = sisaWaktuUTS % 60;
        document.getElementById('display-timer').innerText = 
            `${menit.toString().padStart(2, '0')}:${detik.toString().padStart(2, '0')}`;

        if (sisaWaktuUTS <= 0) {
            clearInterval(timerUTS);
            alert('Waktu UTS telah habis!');
            selesaiUTS();
        }
        sisaWaktuUTS--;
    }

    function tampilkanSoalUTS() {
        const container = document.getElementById('container-uts');
        container.innerHTML = '';

        soalUTS.forEach((item, index) => {
            const el = document.createElement('div');
            el.className = 'card-soal';
            el.innerHTML = `
                <p><strong>${item.soal}</strong></p>
                <div class="opsi-container">
                    ${item.opsi.map((ops, i) => `
                        <button class="btn-opsi opsi-uts-${index}" onclick="pilihJawabanUTS(${index}, ${i}, this)">${ops}</button>
                    `).join('')}
                </div>
            `;
            container.appendChild(el);
        });
    }

    function pilihJawabanUTS(indexSoal, opsiDipilih, btn) {
        jawabanUTS[indexSoal] = opsiDipilih;
        const sekelompok = document.querySelectorAll(`.opsi-uts-${indexSoal}`);
        sekelompok.forEach(b => b.style.backgroundColor = '#ffffff');
        btn.style.backgroundColor = '#bfdbfe'; // Tandai warna biru muda saat dipilih
    }

    function selesaiUTS() {
        clearInterval(timerUTS);

        let skorUTS = 0;
        soalUTS.forEach((item, index) => {
            if (jawabanUTS[index] === item.kunci) {
                skorUTS += (100 / soalUTS.length);
            }
        });

        const waktuSelesai = new Date().toLocaleTimeString('id-ID');
        
        // Simpan ke Leaderboard Real-Time (LocalStorage Browser)
        const dataBaru = {
            nama: siswaAktiv.nama,
            kelas: siswaAktiv.kelas,
            nilai: skorUTS,
            waktu: waktuSelesai
        };

        let listLeaderboard = JSON.parse(localStorage.getItem('leaderboard_uts') || '[]');
        listLeaderboard.push(dataBaru);
        
        // Urutkan nilai tertinggi ke terendah
        listLeaderboard.sort((a, b) => b.nilai - a.nilai);
        
        localStorage.setItem('leaderboard_uts', JSON.stringify(listLeaderboard));

        alert(`Ujian Selesai!\nNama: ${siswaAktiv.nama}\nNilai UTS Anda: ${skorUTS}`);
        bukaSection('sec-leaderboard');
    }

    // --- LEADERBOARD REAL-TIME ---
    function muatLeaderboard() {
        const tbody = document.getElementById('tbody-leaderboard');
        tbody.innerHTML = '';

        let listLeaderboard = JSON.parse(localStorage.getItem('leaderboard_uts') || '[]');

        if (listLeaderboard.length === 0) {
            tbody.innerHTML = `<tr><td colspan="5">Belum ada peserta yang menyelesaikan Simulasi UTS.</td></tr>`;
            return;
        }

        listLeaderboard.forEach((item, index) => {
            const tr = document.createElement('tr');
            tr.innerHTML = `
                <td>${index + 1}</td>
                <td>${item.nama}</td>
                <td>${item.kelas}</td>
                <td><strong>${item.nilai}</strong></td>
                <td>${item.waktu}</td>
            `;
            tbody.appendChild(tr);
        });
    }

    // Inisialisasi awal
    tampilkanLatihan();
</script>

</body>
</html>

26,191 chars · codepastes.com