MATERI INFORMATIKA 1

https://share.gemini.google/Tzy2486AYpjD


<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>E-Learning Informatika - Semester 1 & 2</title>
    <!-- Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- FontAwesome Icons -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <!-- Google Fonts: Plus Jakarta Sans -->
    <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {

                extend: {
                    fontFamily: {
                        sans: ['Plus Jakarta Sans', 'sans-serif'],
                    },
                    colors: {
                        brand: {
                            50: '#f0f7ff',
                            100: '#e0effe',
                            500: '#3b82f6',
                            600: '#2563eb',
                            700: '#1d4ed8',
                            900: '#1e3a8a',
                        },
                        cyber: {
                            dark: '#0f172a',
                            card: '#1e293b',
                            accent: '#10b981'
                        }
                    }
                }
            }
        }
    </script>
    <style>
        .glass-panel {
            background: rgba(30, 41, 59, 0.7);
            backdrop-filter: blur(12px);
            border: 1px solid rgba(255, 255, 255, 0.08);
        }
        .custom-scrollbar::-webkit-scrollbar {
            width: 6px;
            height: 6px;
        }
        .custom-scrollbar::-webkit-scrollbar-track {
            background: rgba(15, 23, 42, 0.5);
        }
        .custom-scrollbar::-webkit-scrollbar-thumb {
            background: rgba(59, 130, 246, 0.5);
            border-radius: 3px;
        }
    </style>
</head>
<body class="bg-[#0b0f19] text-slate-100 min-h-screen font-sans antialiased selection:bg-brand-500 selection:text-white">

    <!-- GATEKEEPER LOCK SCREEN OVERLAY -->
    <div id="gatekeeperOverlay" class="fixed inset-0 z-50 bg-[#070a13] flex flex-col items-center justify-center p-4 transition-all duration-500">
        <div class="absolute inset-0 bg-[radial-gradient(circle_at_50%_40%,rgba(59,130,246,0.15),transparent_60%)]"></div>
        <div class="absolute w-72 h-72 bg-emerald-500/5 rounded-full blur-3xl top-10 left-10"></div>
        
        <div class="relative z-10 w-full max-w-md bg-slate-900/80 backdrop-blur-xl border border-slate-800 rounded-3xl p-6 sm:p-8 shadow-2xl text-center space-y-6">
            <div class="w-16 h-16 bg-gradient-to-tr from-brand-600 to-emerald-500 rounded-2xl flex items-center justify-center mx-auto shadow-lg shadow-brand-500/20">
                <i class="fa-solid fa-laptop-code text-white text-2xl"></i>
            </div>
            <div>
                <h2 class="text-2xl font-extrabold tracking-tight bg-gradient-to-r from-white via-slate-200 to-brand-400 bg-clip-text text-transparent">INFO-LEARN</h2>
                <p class="text-xs text-slate-400 mt-1 uppercase tracking-widest font-bold">Portal Informatika Interaktif</p>
            </div>

            <!-- Role Selector -->
            <div class="space-y-2 text-left">
                <label class="block text-xs font-semibold text-slate-400 uppercase tracking-wider">Pilih Peran Masuk:</label>
                <div class="grid grid-cols-2 gap-3">
                    <button type="button" id="roleBtnSiswa" onclick="selectGatekeeperRole('siswa')" class="flex flex-col items-center justify-center p-4 rounded-2xl border transition-all duration-300 bg-brand-500/10 border-brand-500/50 text-white">
                        <i class="fa-solid fa-user-graduate text-xl mb-1 text-brand-400"></i>
                        <span class="text-xs font-bold">Siswa</span>
                    </button>
                    <button type="button" id="roleBtnGuru" onclick="selectGatekeeperRole('guru')" class="flex flex-col items-center justify-center p-4 rounded-2xl border transition-all duration-300 bg-slate-950 border-slate-800 text-slate-400 hover:border-slate-700 hover:text-slate-200">
                        <i class="fa-solid fa-user-tie text-xl mb-1 text-slate-500"></i>
                        <span class="text-xs font-bold">Guru</span>
                    </button>
                </div>
            </div>

            <!-- Password Input -->
            <div class="space-y-2 text-left">
                <label id="gatekeeperLabel" class="block text-xs font-semibold text-slate-400 uppercase tracking-wider">Kode Akses Siswa:</label>
                <input type="password" id="gatekeeperCodeInput" onkeydown="if(event.key === 'Enter') checkGatekeeperCode()" class="w-full px-4 py-3 bg-slate-950 border border-slate-800 rounded-xl outline-none focus:border-brand-500 text-slate-100 text-center font-bold tracking-widest text-xl placeholder:tracking-normal placeholder:font-normal" placeholder="12345">
                <p id="gatekeeperError" class="text-xs text-red-400 hidden flex items-center justify-center gap-1.5 mt-2">
                    <i class="fa-solid fa-circle-exclamation"></i> Kode akses tidak valid! Silakan periksa kembali.
                </p>
            </div>

            <div class="pt-2">
                <button onclick="checkGatekeeperCode()" class="w-full py-3 bg-gradient-to-r from-brand-600 to-brand-700 hover:from-brand-500 hover:to-brand-600 text-white font-bold rounded-xl transition shadow-lg shadow-brand-500/25">
                    Mulai Masuk <i class="fa-solid fa-arrow-right ml-1"></i>
                </button>
            </div>
            <div class="text-[10px] text-slate-500">
                Akses Siswa: <span class="font-mono text-slate-400">12345</span> | Akses Guru: <span class="font-mono text-slate-400">5678</span>
            </div>
        </div>
    </div>

    <!-- App Container -->
    <div class="flex flex-col min-h-screen">
        
        <!-- Header / Navigation -->
        <header class="sticky top-0 z-40 glass-panel border-b border-slate-800">
            <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-20 flex items-center justify-between">
                <div class="flex items-center gap-3">
                    <div class="w-11 h-11 bg-gradient-to-tr from-brand-600 to-emerald-500 rounded-xl flex items-center justify-center shadow-lg shadow-brand-500/20">
                        <i class="fa-solid fa-laptop-code text-white text-xl"></i>
                    </div>
                    <div>
                        <h1 class="font-extrabold text-lg sm:text-xl tracking-tight bg-gradient-to-r from-white via-slate-200 to-brand-400 bg-clip-text text-transparent">
                            INFO-LEARN
                        </h1>
                        <p class="text-xs text-slate-400 font-medium">Platform Informatika Interaktif</p>
                    </div>
                </div>

                <div class="flex items-center gap-4">
                    <!-- Dynamic Role Switcher (Siswa/Guru Switcher) -->
                    <div class="flex items-center gap-2 bg-slate-950 p-1 rounded-2xl border border-slate-800">
                        <button id="headerBtnSiswa" onclick="switchHeaderRole('siswa')" class="px-3.5 py-1.5 rounded-xl text-xs font-bold transition-all duration-300 flex items-center gap-1.5 bg-brand-600 text-white shadow-md">
                            <i class="fa-solid fa-user-graduate"></i> Siswa
                        </button>
                        <button id="headerBtnGuru" onclick="switchHeaderRole('guru')" class="px-3.5 py-1.5 rounded-xl text-xs font-bold transition-all duration-300 flex items-center gap-1.5 text-slate-400 hover:text-slate-200">
                            <i class="fa-solid fa-user-tie"></i> Guru
                        </button>
                    </div>
                    
                    <!-- Progres Global Ring -->
                    <div class="hidden md:flex items-center gap-3 bg-slate-900/60 py-1.5 px-3.5 rounded-xl border border-slate-800">
                        <div class="text-right">
                            <span class="block text-xs text-slate-400">Selesai Belajar</span>
                            <span id="globalPercentText" class="text-sm font-bold text-emerald-400">0%</span>
                        </div>
                        <div class="relative w-10 h-10">
                            <svg class="w-full h-full transform -rotate-90">
                                <circle cx="20" cy="20" r="16" stroke="currentColor" stroke-width="4" class="text-slate-800" fill="transparent" />
                                <circle id="progressCircle" cx="20" cy="20" r="16" stroke="currentColor" stroke-width="4" class="text-emerald-500" fill="transparent"
                                    stroke-dasharray="100.5" stroke-dashoffset="100.5" stroke-linecap="round" />
                            </svg>
                        </div>
                    </div>
                </div>
            </div>
        </header>

        <!-- Main Content Section -->
        <main class="flex-grow max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8 py-8">
            
            <!-- Hero Banner -->
            <div class="relative overflow-hidden rounded-3xl bg-gradient-to-r from-slate-900 via-brand-950 to-slate-900 border border-slate-800 p-6 sm:p-10 mb-6 shadow-2xl">
                <div class="absolute inset-0 bg-[radial-gradient(circle_at_30%_30%,rgba(59,130,246,0.1),transparent_50%)]"></div>
                <div class="absolute -right-10 -bottom-10 w-48 h-48 bg-emerald-500/10 rounded-full blur-3xl"></div>
                
                <div class="relative z-10 grid md:grid-cols-3 gap-6 items-center">
                    <div class="md:col-span-2 space-y-3">
                        <span class="inline-flex items-center gap-1.5 py-1 px-3 rounded-full text-xs font-semibold bg-brand-500/10 text-brand-400 border border-brand-500/20">
                            <span class="w-2 h-2 rounded-full bg-brand-500 animate-pulse"></span>
                            Tahun Ajaran Aktif
                        </span>
                        <h2 class="text-2xl sm:text-4xl font-extrabold tracking-tight text-white leading-tight">
                            E-Learning Informatika <br class="hidden sm:inline">Kurikulum Merdeka 1 Semester
                        </h2>
                        <p class="text-sm sm:text-base text-slate-300 max-w-xl">
                            Selamat datang di portal belajar interaktif. Akses modul, tonton materi pembelajaran, uji pemahaman Anda, serta kumpulkan tugas di sini secara instan.
                        </p>
                    </div>
                    
                    <!-- Stats Card -->
                    <div class="bg-slate-950/60 border border-slate-800 rounded-2xl p-4 sm:p-5 flex flex-col justify-between gap-4">
                        <div>
                            <span class="text-xs text-slate-400 block mb-1">PROGRES BELAJAR SISWA</span>
                            <div class="flex items-baseline gap-2">
                                <span id="completedCount" class="text-3xl font-extrabold text-white">0</span>
                                <span class="text-slate-500">/</span>
                                <span id="totalCount" class="text-lg font-bold text-slate-400">17</span>
                                <span class="text-xs text-slate-400 ml-1">Sub-Bab selesai</span>
                            </div>
                        </div>
                        <div class="w-full bg-slate-800 rounded-full h-2">
                            <div id="globalProgressBar" class="bg-gradient-to-r from-brand-500 to-emerald-400 h-2 rounded-full transition-all duration-500" style="width: 0%"></div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Utama Blog / Materi Utama Section (Materi Penting) -->
            <div class="bg-gradient-to-r from-slate-900 to-slate-950 border border-slate-800 rounded-2xl p-5 mb-8 flex flex-col sm:flex-row items-center justify-between gap-4 shadow-xl">
                <div class="flex items-center gap-4">
                    <div class="w-12 h-12 bg-amber-500/10 rounded-xl flex items-center justify-center border border-amber-500/20 text-amber-400">
                        <i class="fa-solid fa-star text-xl animate-pulse"></i>
                    </div>
                    <div>
                        <span class="text-xs font-semibold uppercase tracking-wider text-amber-400 block">Pusat Informasi & Blog Pembelajaran</span>
                        <h4 class="text-base font-bold text-white">Blog Portal Pembelajaran Informatika Utama</h4>
                        <p class="text-xs text-slate-400">Gunakan link ini untuk membaca ringkasan materi terlengkap semester ini.</p>
                    </div>
                </div>
                <a href="https://suryogarage.blogspot.com/2025/07/informatika.html" target="_blank" class="w-full sm:w-auto text-center px-5 py-3 rounded-xl bg-gradient-to-r from-amber-500 to-orange-500 hover:from-amber-600 hover:to-orange-600 text-slate-950 font-bold text-xs sm:text-sm tracking-wide shadow-lg shadow-amber-500/10 transition">
                    <i class="fa-solid fa-book-open mr-1.5"></i> Buka Materi Blog Utama
                </a>
            </div>

            <!-- Toolbar & Search -->
            <div class="flex flex-col sm:flex-row gap-4 items-center justify-between mb-8">
                <!-- Search bar -->
                <div class="relative w-full sm:max-w-md">
                    <span class="absolute inset-y-0 left-0 flex items-center pl-3.5 pointer-events-none text-slate-400">
                        <i class="fa-solid fa-magnifying-glass"></i>
                    </span>
                    <input type="text" id="searchInput" onkeyup="filterContent()" placeholder="Cari materi, video, kuis..." 
                        class="w-full pl-10 pr-4 py-3 bg-slate-900/60 border border-slate-800 rounded-xl focus:ring-2 focus:ring-brand-500 focus:border-transparent outline-none transition text-sm text-slate-200 placeholder:text-slate-500" />
                </div>

                <!-- Category Filters -->
                <div class="flex items-center gap-2 overflow-x-auto w-full sm:w-auto pb-2 sm:pb-0 custom-scrollbar">
                    <button onclick="filterType('all')" class="type-filter-btn px-4 py-2 rounded-xl text-xs sm:text-sm font-semibold bg-brand-600 text-white shadow-lg shadow-brand-500/20 whitespace-nowrap transition">
                        Semua Tipe
                    </button>
                    <button onclick="filterType('Materi')" class="type-filter-btn px-4 py-2 rounded-xl text-xs sm:text-sm font-medium bg-slate-800 text-slate-400 hover:text-white hover:bg-slate-700 whitespace-nowrap transition">
                        <i class="fa-regular fa-file-lines text-blue-400 mr-1"></i> Materi (PDF)
                    </button>
                    <button onclick="filterType('Video')" class="type-filter-btn px-4 py-2 rounded-xl text-xs sm:text-sm font-medium bg-slate-800 text-slate-400 hover:text-white hover:bg-slate-700 whitespace-nowrap transition">
                        <i class="fa-regular fa-circle-play text-red-400 mr-1"></i> Video
                    </button>
                    <button onclick="filterType('Kuis')" class="type-filter-btn px-4 py-2 rounded-xl text-xs sm:text-sm font-medium bg-slate-800 text-slate-400 hover:text-white hover:bg-slate-700 whitespace-nowrap transition">
                        <i class="fa-solid fa-laptop-code text-amber-400 mr-1"></i> Kuis/Tugas
                    </button>
                </div>
            </div>

            <!-- Teacher Control Panel (Hanya muncul jika Mode Guru Aktif) -->
            <div id="teacherPanel" class="hidden bg-slate-900 border border-amber-500/30 rounded-3xl p-6 mb-8 relative">
                <div class="absolute -top-3 left-6 px-3 py-1 bg-amber-500 text-slate-950 font-bold text-xs rounded-full uppercase tracking-wider animate-bounce">
                    Panel Kontrol Guru
                </div>
                <div class="flex flex-col gap-6">
                    <div class="grid md:grid-cols-2 gap-6 items-center border-b border-slate-800/80 pb-6">
                        <div>
                            <h3 class="text-lg font-bold text-white mb-2">Kelola Link & Pembelajaran</h3>
                            <p class="text-sm text-slate-300">
                                Sebagai guru, Anda dapat menekan tombol edit <i class="fa-solid fa-pen text-amber-400"></i> pada setiap sub-bab di bawah untuk menyematkan link materi atau memeriksa rekap jawaban siswa yang masuk di tabel bawah.
                            </p>
                        </div>
                        <div class="flex flex-wrap gap-3 md:justify-end">
                            <button onclick="exportData()" class="flex items-center gap-2 px-4 py-2.5 bg-emerald-600 hover:bg-emerald-500 text-white font-semibold rounded-xl text-sm transition shadow-lg shadow-emerald-600/10">
                                <i class="fa-solid fa-download"></i> Ekspor Link (.json)
                            </button>
                            <button onclick="triggerImport()" class="flex items-center gap-2 px-4 py-2.5 bg-slate-800 hover:bg-slate-700 border border-slate-700 text-white font-semibold rounded-xl text-sm transition">
                                <i class="fa-solid fa-upload"></i> Impor Link (.json)
                            </button>
                            <input type="file" id="importFileInput" onchange="importData(event)" class="hidden" accept=".json">
                        </div>
                    </div>

                    <!-- Rekap Jawaban Siswa -->
                    <div>
                        <div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-4">
                            <div class="flex items-center gap-2">
                                <span class="p-2 bg-brand-500/10 text-brand-400 rounded-lg">
                                    <i class="fa-solid fa-user-graduate"></i>
                                </span>
                                <h3 class="text-base font-bold text-white">Daftar & Rekap Jawaban Siswa</h3>
                            </div>
                            
                            <!-- Filter Kelas Guru -->
                            <div class="flex gap-2">
                                <select id="teacherClassFilter" onchange="renderSubmissions()" class="px-3 py-1.5 bg-slate-950 border border-slate-800 rounded-lg text-xs font-semibold text-slate-300 focus:border-brand-500 outline-none">
                                    <option value="all">Semua Kelas</option>
                                    <option value="X OTO1">X OTO1</option>
                                    <option value="AV">AV</option>
                                    <option value="MPLB">MPLB</option>
                                    <option value="AKL">AKL</option>
                                    <option value="X OTO2">X OTO2</option>
                                </select>
                            </div>
                        </div>

                        <!-- Table Rekap Jawaban -->
                        <div class="overflow-x-auto custom-scrollbar border border-slate-800 rounded-2xl bg-slate-950/40">
                            <table class="w-full text-left border-collapse">
                                <thead>
                                    <tr class="border-b border-slate-800 bg-slate-900/60 text-xs font-bold text-slate-400 uppercase tracking-wider">
                                        <th class="p-4">Siswa & Kelas</th>
                                        <th class="p-4">Sub-Bab</th>
                                        <th class="p-4">Tanggal Pengiriman</th>
                                        <th class="p-4">Link Lampiran</th>
                                        <th class="p-4">Status & Nilai</th>
                                        <th class="p-4 text-center">Aksi</th>
                                    </tr>
                                </thead>
                                <tbody id="submissionsTableBody" class="divide-y divide-slate-800 text-sm text-slate-300">
                                    <!-- Dynamic rows from js -->
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Chapters Grid Container -->
            <div class="grid grid-cols-1 lg:grid-cols-2 gap-8" id="chaptersContainer">
                <!-- Chapters will be injected dynamically via JavaScript -->
            </div>

        </main>

        <!-- Footer -->
        <footer class="mt-auto border-t border-slate-800/80 bg-slate-950 py-8 text-center text-slate-500">
            <div class="max-w-7xl mx-auto px-4">
                <p class="text-sm">© 2026 E-Learning Informatika. Semua Hak Cipta Dilindungi.</p>
                <p class="text-xs text-slate-600 mt-2">Didesain untuk keaktifan belajar siswa secara mandiri & terstruktur.</p>
            </div>
        </footer>

    </div>

    <!-- Notification Container -->
    <div id="toast" class="fixed bottom-6 right-6 z-50 transform translate-y-12 opacity-0 transition-all duration-300 pointer-events-none">
        <div class="flex items-center gap-3 bg-slate-900 border border-brand-500 text-slate-100 py-3.5 px-6 rounded-xl shadow-2xl">
            <div class="w-2.5 h-2.5 rounded-full bg-emerald-500 animate-pulse"></div>
            <span id="toastMsg" class="text-sm font-semibold">Tautan berhasil disimpan!</span>
        </div>
    </div>

    <!-- Edit Link Modal (Guru Mode) -->
    <div id="editModal" class="fixed inset-0 z-50 hidden bg-slate-950/80 backdrop-filter backdrop-blur-sm flex items-center justify-center p-4">
        <div class="bg-slate-900 border border-slate-800 w-full max-w-lg rounded-3xl overflow-hidden shadow-2xl relative">
            <div class="p-6 border-b border-slate-800 flex items-center justify-between">
                <h3 class="text-lg font-bold text-white flex items-center gap-2">
                    <i class="fa-solid fa-edit text-amber-500"></i> Edit Materi Pembelajaran
                </h3>
                <button onclick="closeEditModal()" class="text-slate-400 hover:text-white transition">
                    <i class="fa-solid fa-xmark text-xl"></i>
                </button>
            </div>
            
            <div class="p-6 space-y-4">
                <div>
                    <label class="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Nama Sub-Bab</label>
                    <input type="text" id="editSubName" class="w-full px-4 py-2.5 bg-slate-950 border border-slate-800 rounded-xl outline-none focus:border-brand-500 text-slate-100 text-sm" placeholder="Contoh: Algoritma Pencarian">
                </div>
                
                <div class="grid grid-cols-2 gap-4">
                    <div>
                        <label class="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Tipe Materi</label>
                        <select id="editSubCategory" class="w-full px-4 py-2.5 bg-slate-950 border border-slate-800 rounded-xl outline-none focus:border-brand-500 text-slate-100 text-sm">
                            <option value="Materi">Materi (PDF/Doc)</option>
                            <option value="Video">Video Tutorial</option>
                            <option value="Kuis">Kuis & Tugas</option>
                        </select>
                    </div>
                    <div>
                        <label class="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Estimasi Waktu</label>
                        <input type="text" id="editSubDuration" class="w-full px-4 py-2.5 bg-slate-950 border border-slate-800 rounded-xl outline-none focus:border-brand-500 text-slate-100 text-sm" placeholder="Contoh: 15 Menit">
                    </div>
                </div>

                <div>
                    <label class="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Tautan / Link Sumber</label>
                    <input type="text" id="editSubLink" class="w-full px-4 py-2.5 bg-slate-950 border border-slate-800 rounded-xl outline-none focus:border-brand-500 text-slate-100 text-sm" placeholder="Masukkan Link Drive/YouTube/Wordwall">
                </div>

                <div>
                    <label class="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Deskripsi Singkat / Instruksi Tugas</label>
                    <textarea id="editSubDesc" rows="3" class="w-full px-4 py-2.5 bg-slate-950 border border-slate-800 rounded-xl outline-none focus:border-brand-500 text-slate-100 text-sm" placeholder="Berikan instruksi belajar untuk siswa..."></textarea>
                </div>
            </div>

            <div class="p-6 bg-slate-950 border-t border-slate-800 flex justify-end gap-3">
                <button onclick="closeEditModal()" class="px-4 py-2 text-sm font-semibold text-slate-400 hover:text-white transition">
                    Batal
                </button>
                <button onclick="saveEditData()" class="px-5 py-2 text-sm font-semibold bg-brand-600 hover:bg-brand-500 text-white rounded-xl transition">
                    Simpan Perubahan
                </button>
            </div>
        </div>
    </div>

    <!-- Kirim Tugas Modal (Siswa View) -->
    <div id="submitTaskModal" class="fixed inset-0 z-50 hidden bg-slate-950/80 backdrop-filter backdrop-blur-sm flex items-center justify-center p-4">
        <div class="bg-slate-900 border border-slate-800 w-full max-w-lg rounded-3xl overflow-hidden shadow-2xl relative">
            <div class="p-6 border-b border-slate-800 flex items-center justify-between">
                <h3 class="text-lg font-bold text-white flex items-center gap-2">
                    <i class="fa-solid fa-paper-plane text-brand-400"></i> Kirim Jawaban & Tugas Siswa
                </h3>
                <button onclick="closeSubmitTaskModal()" class="text-slate-400 hover:text-white transition">
                    <i class="fa-solid fa-xmark text-xl"></i>
                </button>
            </div>
            
            <div class="p-6 space-y-4">
                <div class="p-3 bg-slate-950 border border-slate-800 rounded-2xl">
                    <span class="text-[10px] font-bold text-brand-400 uppercase tracking-wider block">Sub-Bab Tugas</span>
                    <span id="submitModalSubTitle" class="text-sm font-semibold text-white">Judul Sub-Bab</span>
                </div>

                <div class="grid grid-cols-2 gap-4">
                    <div>
                        <label class="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Nama Lengkap</label>
                        <input type="text" id="studentNameInput" class="w-full px-4 py-2.5 bg-slate-950 border border-slate-800 rounded-xl outline-none focus:border-brand-500 text-slate-100 text-sm" placeholder="Nama Anda">
                    </div>
                    <div>
                        <label class="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Kelas</label>
                        <select id="studentClassInput" class="w-full px-4 py-2.5 bg-slate-950 border border-slate-800 rounded-xl outline-none focus:border-brand-500 text-slate-100 text-sm">
                            <option value="X OTO1">X OTO1</option>
                            <option value="AV">AV</option>
                            <option value="MPLB">MPLB</option>
                            <option value="AKL">AKL</option>
                            <option value="X OTO2">X OTO2</option>
                        </select>
                    </div>
                </div>

                <div>
                    <label class="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Teks Jawaban / Keterangan</label>
                    <textarea id="studentNotesInput" rows="3" class="w-full px-4 py-2.5 bg-slate-950 border border-slate-800 rounded-xl outline-none focus:border-brand-500 text-slate-100 text-sm" placeholder="Tuliskan esai jawaban atau ringkasan pengerjaan tugas..."></textarea>
                </div>

                <div>
                    <label class="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Link Lampiran Tugas (Opsional)</label>
                    <input type="text" id="studentLinkInput" class="w-full px-4 py-2.5 bg-slate-950 border border-slate-800 rounded-xl outline-none focus:border-brand-500 text-slate-100 text-sm" placeholder="https://drive.google.com/contoh-tugas-anda">
                    <span class="text-[10px] text-slate-500 mt-1 block">Sertakan link Google Drive, Docs, Wordwall, atau blog hasil pengerjaan Anda.</span>
                </div>
            </div>

            <div class="p-6 bg-slate-950 border-t border-slate-800 flex justify-end gap-3">
                <button onclick="closeSubmitTaskModal()" class="px-4 py-2 text-sm font-semibold text-slate-400 hover:text-white transition">
                    Batal
                </button>
                <button onclick="submitStudentTask()" class="px-5 py-2 text-sm font-semibold bg-brand-600 hover:bg-brand-500 text-white rounded-xl transition">
                    Kirim Jawaban
                </button>
            </div>
        </div>
    </div>

    <!-- Penilaian Guru Modal -->
    <div id="gradeModal" class="fixed inset-0 z-50 hidden bg-slate-950/80 backdrop-filter backdrop-blur-sm flex items-center justify-center p-4">
        <div class="bg-slate-900 border border-slate-800 w-full max-w-md rounded-3xl overflow-hidden shadow-2xl relative">
            <div class="p-6 border-b border-slate-800 flex items-center justify-between">
                <h3 class="text-lg font-bold text-white flex items-center gap-2">
                    <i class="fa-solid fa-graduation-cap text-emerald-400"></i> Form Penilaian Guru
                </h3>
                <button onclick="closeGradeModal()" class="text-slate-400 hover:text-white transition">
                    <i class="fa-solid fa-xmark text-xl"></i>
                </button>
            </div>
            
            <div class="p-6 space-y-4">
                <div class="p-4 bg-slate-950 border border-slate-800 rounded-2xl space-y-2">
                    <div class="flex justify-between items-center text-xs">
                        <span id="gradeModalClass" class="px-2.5 py-0.5 rounded-full bg-slate-800 text-slate-300 font-bold">X-A</span>
                        <span id="gradeModalDate" class="text-slate-500">2026-06-26</span>
                    </div>
                    <h4 id="gradeModalStudentName" class="font-bold text-white text-base">Nama Siswa</h4>
                    <p id="gradeModalSubName" class="text-xs text-brand-400 font-semibold">Nama Sub-Bab</p>
                    
                    <div class="mt-3 pt-3 border-t border-slate-800/80">
                        <span class="text-[10px] font-bold text-slate-500 uppercase block mb-1">Jawaban Siswa:</span>
                        <p id="gradeModalResponseText" class="text-xs text-slate-300 italic leading-relaxed whitespace-pre-wrap">Isi jawaban...</p>
                    </div>
                </div>

                <div>
                    <label class="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Nilai Tugas (0 - 100)</label>
                    <input type="number" id="gradeScoreInput" min="0" max="100" class="w-full px-4 py-2.5 bg-slate-950 border border-slate-800 rounded-xl outline-none focus:border-brand-500 text-slate-100 text-sm font-bold text-emerald-400" placeholder="Masukkan Angka">
                </div>

                <div>
                    <label class="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Umpan Balik / Catatan Guru</label>
                    <textarea id="gradeFeedbackInput" rows="3" class="w-full px-4 py-2.5 bg-slate-950 border border-slate-800 rounded-xl outline-none focus:border-brand-500 text-slate-100 text-sm" placeholder="Tulis masukan konstruktif untuk siswa..."></textarea>
                </div>
            </div>

            <div class="p-6 bg-slate-950 border-t border-slate-800 flex justify-end gap-3">
                <button onclick="closeGradeModal()" class="px-4 py-2 text-sm font-semibold text-slate-400 hover:text-white transition">
                    Batal
                </button>
                <button onclick="saveStudentGrade()" class="px-5 py-2 text-sm font-semibold bg-emerald-600 hover:bg-emerald-500 text-white rounded-xl transition">
                    Simpan Nilai
                </button>
            </div>
        </div>
    </div>

    <!-- Password Verifikasi Modal (Saat ganti ke mode guru dari header) -->
    <div id="passwordModal" class="fixed inset-0 z-50 hidden bg-slate-950/80 backdrop-filter backdrop-blur-sm flex items-center justify-center p-4">
        <div class="bg-slate-900 border border-slate-800 w-full max-w-sm rounded-3xl overflow-hidden shadow-2xl relative">
            <div class="p-6 border-b border-slate-800 flex items-center justify-between">
                <h3 class="text-lg font-bold text-white flex items-center gap-2">
                    <i class="fa-solid fa-key text-amber-500"></i> Verifikasi Akses Guru
                </h3>
                <button onclick="closePasswordModal()" class="text-slate-400 hover:text-white transition">
                    <i class="fa-solid fa-xmark text-xl"></i>
                </button>
            </div>
            <div class="p-6 space-y-4">
                <p class="text-xs text-slate-400 leading-relaxed">Silakan masukkan kata sandi khusus Guru untuk mengakses Panel Kontrol dan mengelola tautan pembelajaran semester ini.</p>
                <div>
                    <label class="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Kata Sandi Guru</label>
                    <input type="password" id="teacherPasswordInput" onkeydown="if(event.key === 'Enter') verifyTeacherPassword()" class="w-full px-4 py-2.5 bg-slate-950 border border-slate-800 rounded-xl outline-none focus:border-brand-500 text-slate-100 text-center font-bold tracking-widest text-lg" placeholder="••••">
                    <p id="passwordError" class="text-xs text-red-400 mt-1.5 hidden flex items-center gap-1.5">
                        <i class="fa-solid fa-circle-exclamation"></i> Kata sandi salah! Hubungi Administrator.
                    </p>
                </div>
            </div>
            <div class="p-6 bg-slate-950 border-t border-slate-800 flex justify-end gap-3">
                <button onclick="closePasswordModal()" class="px-4 py-2 text-sm font-semibold text-slate-400 hover:text-white transition">
                    Batal
                </button>
                <button onclick="verifyTeacherPassword()" class="px-5 py-2 text-sm font-semibold bg-amber-500 hover:bg-amber-600 text-slate-950 rounded-xl transition font-bold">
                    Masuk Mode Guru
                </button>
            </div>
        </div>
    </div>

    <!-- JavaScript Data and Interaction Logic -->
    <script>
        // Data Struktur Bab 1 - 5 Kurikulum Merdeka Informatika
        let informaticsData = [
            {
                id: "bab1",
                num: "Bab 1",
                title: "Berpikir Komputasional",
                desc: "Fondasi dalam memecahkan masalah kompleks menggunakan konsep ilmu komputer.",
                color: "from-blue-600/20 to-indigo-600/20 border-blue-500/30",
                icon: "fa-solid fa-brain",
                subs: [
                    { id: "1_1", name: "Pencarian (Searching)", cat: "Materi", link: "https://suryogarage.blogspot.com/2025/07/informatika.html", duration: "10 Menit", desc: "Membahas konsep pencarian data secara komprehensif pada portal utama." },
                    { id: "1_2", name: "Pengurutan (Sorting)", cat: "Video", link: "https://youtube.com", duration: "15 Menit", desc: "Menjelaskan visualisasi Bubble Sort, Selection Sort, dan Insertion Sort." },
                    { id: "1_3", name: "Tumpukan (Stack) & Antrean (Queue)", cat: "Materi", link: "https://suryogarage.blogspot.com/2025/07/informatika.html", duration: "12 Menit", desc: "Memahami struktur penyimpanan LIFO dan FIFO dalam kehidupan nyata." },
                    { id: "1_4", name: "Kuis Berpikir Komputasional", cat: "Kuis", link: "https://quizizz.com", duration: "20 Menit", desc: "Asah logikamu lewat tantangan Bebras dan kuis komputasi." }
                ]
            },
            {
                id: "bab2",
                num: "Bab 2",
                title: "Teknologi Informasi & Komunikasi",
                desc: "Pemanfaatan aplikasi perkantoran terintegrasi dan kolaborasi awan.",
                color: "from-emerald-600/20 to-teal-600/20 border-emerald-500/30",
                icon: "fa-solid fa-folder-open",
                subs: [
                    { id: "2_1", name: "Integrasi Konten Aplikasi Perkantoran", cat: "Materi", link: "https://suryogarage.blogspot.com/2025/07/informatika.html", duration: "10 Menit", desc: "Menghubungkan Word, Excel, dan PowerPoint dengan teknik OLE." },
                    { id: "2_2", name: "Fitur Lanjut Mail Merge", cat: "Video", link: "https://youtube.com", duration: "8 Menit", desc: "Cara membuat surat massal secara cepat memanfaatkan pangkalan data." },
                    { id: "2_3", name: "Kolaborasi Dokumen di Cloud Storage", cat: "Kuis", link: "https://drive.google.com", duration: "15 Menit", desc: "Praktik membuat dokumen bersama menggunakan Google Docs / OneDrive." }
                ]
            },
            {
                id: "bab3",
                num: "Bab 3",
                title: "Sistem Komputer",
                desc: "Memahami interaksi komponen perangkat keras, lunak, dan pengguna.",
                color: "from-purple-600/20 to-pink-600/20 border-purple-500/30",
                icon: "fa-solid fa-microchip",
                subs: [
                    { id: "3_1", name: "Perangkat Keras (Hardware)", cat: "Materi", link: "https://suryogarage.blogspot.com/2025/07/informatika.html", duration: "12 Menit", desc: "Mengenal unit pemrosesan, input, output, dan media penyimpanan sekunder." },
                    { id: "3_2", name: "Perangkat Lunak & Sistem Operasi", cat: "Video", link: "https://youtube.com", duration: "15 Menit", desc: "Bagaimana Sistem Operasi (Windows, Linux, macOS) mengelola sumber daya komputer." },
                    { id: "3_3", name: "Interaksi Manusia dan Komputer (IMK)", cat: "Materi", link: "https://suryogarage.blogspot.com/2025/07/informatika.html", duration: "10 Menit", desc: "Mempelajari antarmuka grafis (GUI) dan Command Line Interface (CLI)." },
                    { id: "3_4", name: "Evaluasi Komponen Komputer", cat: "Kuis", link: "https://quizizz.com", duration: "15 Menit", desc: "Uji pemahamanmu mengenai cara kerja otak komputer." }
                ]
            },
            {
                id: "bab4",
                num: "Bab 4",
                title: "Jaringan Komputer & Internet",
                desc: "Mempelajari cara kerja transfer data global dan proteksi privasi digital.",
                color: "from-sky-600/20 to-blue-600/20 border-sky-500/30",
                icon: "fa-solid fa-wifi",
                subs: [
                    { id: "4_1", name: "Pengantar Jaringan Komputer & Topologi", cat: "Materi", link: "https://suryogarage.blogspot.com/2025/07/informatika.html", duration: "15 Menit", desc: "Belajar topologi jaringan lokal (LAN), metropolitan (MAN), dan global (WAN)." },
                    { id: "4_2", name: "Enkripsi & Proteksi Data di Internet", cat: "Video", link: "https://youtube.com", duration: "11 Menit", desc: "Mengapa penting menjaga data pribadi dan bagaimana teknik kriptografi dasar bekerja." },
                    { id: "4_3", name: "Kuis Keamanan Jaringan", cat: "Kuis", link: "https://quizizz.com", duration: "15 Menit", desc: "Praktik mengenali phishing dan situs web aman (HTTPS)." }
                ]
            },
            {
                id: "bab5",
                num: "Bab 5",
                title: "Analisis Data",
                desc: "Mengolah kumpulan informasi mentah menjadi keputusan terstruktur bernilai.",
                color: "from-amber-600/20 to-orange-600/20 border-amber-500/30",
                icon: "fa-solid fa-chart-pie",
                subs: [
                    { id: "5_1", name: "Pengumpulan Data & Pembersihan (Cleaning)", cat: "Materi", link: "https://suryogarage.blogspot.com/2025/07/informatika.html", duration: "10 Menit", desc: "Teknik menyaring data mentah agar siap dianalisis di aplikasi spreadsheet." },
                    { id: "5_2", name: "Visualisasi Data Interaktif", cat: "Video", link: "https://youtube.com", duration: "12 Menit", desc: "Membangun diagram batang, garis, dan lingkaran yang informatif." },
                    { id: "5_3", name: "Aspek Privasi dan Keamanan Analisis Data", cat: "Kuis", link: "https://quizizz.com", duration: "15 Menit", desc: "Ujian modul akhir mengolah tabel data dan menyajikannya secara etis." }
                ]
            }
        ];

        // Simulasi Jawaban Siswa (Mock Data)
        let studentSubmissions = [
            {
                id: "sub_1",
                studentName: "Dafa Ramadhan",
                studentClass: "X-A",
                subId: "1_4",
                subName: "Kuis Berpikir Komputasional",
                notes: "Saya sudah menyelesaikan latihan bebras di link quizizz yang bapak berikan. Logika dekomposisi sangat membantu.",
                link: "https://quizizz.com/join",
                submittedAt: "2026-06-25 14:22",
                status: "Sudah Dinilai",
                score: "92",
                feedback: "Luar biasa Dafa! Analisis dekomposisinya sudah sangat runtut."
            },
            {
                id: "sub_2",
                studentName: "Amelia Putri",
                studentClass: "X-B",
                subId: "2_3",
                subName: "Kolaborasi Dokumen di Cloud Storage",
                notes: "Berikut adalah tugas folder integrasi kelompok B, kami menggunakan Google Docs.",
                link: "https://drive.google.com/drive/folders/test12345",
                submittedAt: "2026-06-26 09:10",
                status: "Belum Dinilai",
                score: "",
                feedback: ""
            },
            {
                id: "sub_3",
                studentName: "Rian Hidayat",
                studentClass: "X-A",
                subId: "3_4",
                subName: "Evaluasi Komponen Komputer",
                notes: "Jawaban esai: CPU bertugas memproses data, RAM menyimpan sementara, dan harddisk menyimpan permanen.",
                link: "",
                submittedAt: "2026-06-26 11:30",
                status: "Belum Dinilai",
                score: "",
                feedback: ""
            }
        ];

        let selectedGatekeeperRole = 'siswa'; // Default role di Gatekeeper
        let teacherMode = false;
        let selectedSubToEdit = null;
        let selectedSubToSubmit = null;
        let selectedSubmissionToGrade = null;
        let completedSubs = [];
        let currentFilter = 'all';

        // Load data dari Session/Local Storage jika ada
        window.onload = function() {
            const savedData = localStorage.getItem('informatics_elearning_data');
            if (savedData) {
                informaticsData = JSON.parse(savedData);
            }
            
            const savedProgress = localStorage.getItem('informatics_completed_progress');
            if (savedProgress) {
                completedSubs = JSON.parse(savedProgress);
            }

            const savedSubmissions = localStorage.getItem('informatics_student_submissions');
            if (savedSubmissions) {
                studentSubmissions = JSON.parse(savedSubmissions);
            }

            // Periksa Status Keamanan Gerbang (Gatekeeper)
            const unlockedState = sessionStorage.getItem('info_learn_unlocked');
            if (unlockedState === 'student') {
                document.getElementById('gatekeeperOverlay').style.display = 'none';
                teacherMode = false;
                applyRoleState();
            } else if (unlockedState === 'teacher') {
                document.getElementById('gatekeeperOverlay').style.display = 'none';
                teacherMode = true;
                applyRoleState();
            } else {
                // Focus ke password input jika belum di-unlock
                document.getElementById('gatekeeperCodeInput').focus();
            }

            renderDashboard();
            updateProgress();
            renderSubmissions();
        }

        // Simpan data lokal
        function saveToLocalStorage() {
            localStorage.setItem('informatics_elearning_data', JSON.stringify(informaticsData));
            localStorage.setItem('informatics_completed_progress', JSON.stringify(completedSubs));
            localStorage.setItem('informatics_student_submissions', JSON.stringify(studentSubmissions));
        }

        // ================= GATEKEEPER (SCREEN KUNCI) LOGIC =================

        // Memilih peran di Layar Kunci
        function selectGatekeeperRole(role) {
            selectedGatekeeperRole = role;
            const btnSiswa = document.getElementById('roleBtnSiswa');
            const btnGuru = document.getElementById('roleBtnGuru');
            const label = document.getElementById('gatekeeperLabel');
            const input = document.getElementById('gatekeeperCodeInput');

            // Reset error
            document.getElementById('gatekeeperError').classList.add('hidden');

            if (role === 'siswa') {
                btnSiswa.className = "flex flex-col items-center justify-center p-4 rounded-2xl border transition-all duration-300 bg-brand-500/10 border-brand-500/50 text-white";
                btnGuru.className = "flex flex-col items-center justify-center p-4 rounded-2xl border transition-all duration-300 bg-slate-950 border-slate-800 text-slate-400 hover:border-slate-700 hover:text-slate-200";
                label.innerText = "Kode Akses Siswa:";
                input.placeholder = "12345";
            } else {
                btnGuru.className = "flex flex-col items-center justify-center p-4 rounded-2xl border transition-all duration-300 bg-amber-500/10 border-amber-500/50 text-white";
                btnSiswa.className = "flex flex-col items-center justify-center p-4 rounded-2xl border transition-all duration-300 bg-slate-950 border-slate-800 text-slate-400 hover:border-slate-700 hover:text-slate-200";
                label.innerText = "Kode Akses Guru:";
                input.placeholder = "5678";
            }
            input.value = '';
            input.focus();
        }

        // Verifikasi kode akses di Layar Kunci
        function checkGatekeeperCode() {
            const codeInput = document.getElementById('gatekeeperCodeInput');
            const code = codeInput.value.trim();
            const errorElement = document.getElementById('gatekeeperError');

            if (selectedGatekeeperRole === 'siswa' && code === '12345') {
                sessionStorage.setItem('info_learn_unlocked', 'student');
                document.getElementById('gatekeeperOverlay').classList.add('opacity-0', 'pointer-events-none');
                teacherMode = false;
                applyRoleState();
                showToast("Selamat belajar! Kode akses siswa berhasil diterima.");
            } else if (selectedGatekeeperRole === 'guru' && code === '5678') {
                sessionStorage.setItem('info_learn_unlocked', 'teacher');
                document.getElementById('gatekeeperOverlay').classList.add('opacity-0', 'pointer-events-none');
                teacherMode = true;
                applyRoleState();
                showToast("Selamat datang Guru! Masuk langsung ke Panel Kontrol.");
            } else {
                errorElement.classList.remove('hidden');
                codeInput.classList.add('border-red-500');
                setTimeout(() => {
                    codeInput.classList.remove('border-red-500');
                }, 500);
            }
        }

        // ================= HEADER ROLE SWITCHER LOGIC =================

        // Berpindah peran melalui Segmented Control di Header
        function switchHeaderRole(role) {
            if (role === 'siswa') {
                if (teacherMode) {
                    teacherMode = false;
                    sessionStorage.setItem('info_learn_unlocked', 'student');
                    applyRoleState();
                    showToast("Beralih ke Mode Siswa.");
                }
            } else {
                if (!teacherMode) {
                    openPasswordModal(); // Minta kata sandi jika mau masuk mode Guru
                }
            }
        }

        // Buka modal pengaman ganti peran
        function openPasswordModal() {
            document.getElementById('teacherPasswordInput').value = '';
            document.getElementById('passwordError').classList.add('hidden');
            document.getElementById('passwordModal').classList.remove('hidden');
            setTimeout(() => {
                document.getElementById('teacherPasswordInput').focus();
            }, 150);
        }

        function closePasswordModal() {
            document.getElementById('passwordModal').classList.add('hidden');
        }

        // Verifikasi password ganti peran
        function verifyTeacherPassword() {
            const password = document.getElementById('teacherPasswordInput').value;
            const errorElement = document.getElementById('passwordError');
            
            if (password === '5678') {
                teacherMode = true;
                sessionStorage.setItem('info_learn_unlocked', 'teacher');
                closePasswordModal();
                applyRoleState();
                showToast("Mode Guru Berhasil Diaktifkan!");
            } else {
                errorElement.classList.remove('hidden');
                const input = document.getElementById('teacherPasswordInput');
                input.classList.add('border-red-500');
                setTimeout(() => {
                    input.classList.remove('border-red-500');
                }, 500);
            }
        }

        // Terapkan penyesuaian visual berdasarkan Peran Aktif
        function applyRoleState() {
            const btnSiswa = document.getElementById('headerBtnSiswa');
            const btnGuru = document.getElementById('headerBtnGuru');
            const panel = document.getElementById('teacherPanel');

            if (teacherMode) {
                // Style Header Switcher ke Guru
                btnGuru.className = "px-3.5 py-1.5 rounded-xl text-xs font-bold transition-all duration-300 flex items-center gap-1.5 bg-amber-500 text-slate-950 shadow-md";
                btnSiswa.className = "px-3.5 py-1.5 rounded-xl text-xs font-bold transition-all duration-300 flex items-center gap-1.5 text-slate-400 hover:text-slate-200";
                
                panel.classList.remove('hidden');
                renderSubmissions();
            } else {
                // Style Header Switcher ke Siswa
                btnSiswa.className = "px-3.5 py-1.5 rounded-xl text-xs font-bold transition-all duration-300 flex items-center gap-1.5 bg-brand-600 text-white shadow-md";
                btnGuru.className = "px-3.5 py-1.5 rounded-xl text-xs font-bold transition-all duration-300 flex items-center gap-1.5 text-slate-400 hover:text-slate-200";
                
                panel.classList.add('hidden');
            }
            renderDashboard();
        }

        // ================= DASHBOARD & CONTENT LOGIC =================

        // Render Dashboard Bab & Sub-Bab
        function renderDashboard() {
            const container = document.getElementById('chaptersContainer');
            container.innerHTML = '';

            informaticsData.forEach((bab) => {
                let cardHTML = `
                    <div class="glass-panel border rounded-3xl overflow-hidden shadow-lg transition-transform duration-300 hover:scale-[1.01] flex flex-col justify-between ${bab.color}">
                        <div class="p-6">
                            <!-- Bab Header -->
                            <div class="flex items-start justify-between gap-4 mb-4">
                                <div class="space-y-1">
                                    <span class="text-xs font-bold text-slate-400 tracking-widest uppercase">${bab.num}</span>
                                    <h3 class="text-xl font-extrabold text-white leading-tight">${bab.title}</h3>
                                </div>
                                <div class="w-12 h-12 rounded-2xl bg-slate-900/80 border border-slate-700/50 flex items-center justify-center text-slate-300">
                                    <i class="${bab.icon} text-lg"></i>
                                </div>
                            </div>
                            <p class="text-xs sm:text-sm text-slate-300 mb-6 font-medium leading-relaxed">${bab.desc}</p>
                            
                            <!-- Sub Bab List -->
                            <div class="space-y-3.5">
                `;

                bab.subs.forEach((sub) => {
                    const isChecked = completedSubs.includes(sub.id);
                    const isMatchedFilter = currentFilter === 'all' || sub.cat === currentFilter;
                    const visibilityClass = isMatchedFilter ? 'block' : 'hidden';

                    // Badge Color
                    let badgeColor = "bg-blue-500/10 text-blue-400 border-blue-500/20";
                    let badgeIcon = "fa-regular fa-file-lines";
                    if (sub.cat === "Video") {
                        badgeColor = "bg-red-500/10 text-red-400 border-red-500/20";
                        badgeIcon = "fa-regular fa-circle-play";
                    } else if (sub.cat === "Kuis") {
                        badgeColor = "bg-amber-500/10 text-amber-400 border-amber-500/20";
                        badgeIcon = "fa-solid fa-laptop-code";
                    }

                    // Badge status jawaban terkirim
                    const mySubmissions = studentSubmissions.filter(s => s.subId === sub.id);
                    let submissionBadge = "";
                    if (mySubmissions.length > 0) {
                        const graded = mySubmissions.find(s => s.status === "Sudah Dinilai");
                        if (graded) {
                            submissionBadge = `<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-bold bg-emerald-500/10 text-emerald-400 border border-emerald-500/20"><i class="fa-solid fa-award"></i> Nilai: ${graded.score}</span>`;
                        } else {
                            submissionBadge = `<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-bold bg-purple-500/10 text-purple-400 border border-purple-500/20"><i class="fa-solid fa-spinner animate-spin"></i> Terkirim</span>`;
                        }
                    }

                    cardHTML += `
                        <div class="sub-item bg-slate-900/50 border border-slate-800/80 rounded-2xl p-3.5 hover:bg-slate-900 transition flex items-start justify-between gap-3 ${visibilityClass}" data-title="${sub.name.toLowerCase()}">
                            <div class="flex items-start gap-3 flex-grow">
                                <!-- Checkbox Siswa -->
                                <div class="pt-0.5">
                                    <button onclick="toggleSubComplete('${sub.id}')" class="w-5.5 h-5.5 rounded-md border flex items-center justify-center transition-all ${isChecked ? 'bg-emerald-500 border-emerald-500 text-slate-900' : 'border-slate-700 hover:border-slate-500 text-transparent'}" title="Tandai selesai">
                                        <i class="fa-solid fa-check text-xs font-black"></i>
                                    </button>
                                </div>
                                <div class="space-y-1 w-full">
                                    <div class="flex flex-wrap items-center gap-2">
                                        <h4 class="text-xs sm:text-sm font-semibold text-slate-200">${sub.name}</h4>
                                        <span class="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-bold border ${badgeColor}">
                                            <i class="${badgeIcon}"></i> ${sub.cat}
                                        </span>
                                        <span class="text-[10px] text-slate-500"><i class="fa-regular fa-clock mr-1"></i>${sub.duration}</span>
                                        ${submissionBadge}
                                    </div>
                                    <p class="text-xs text-slate-400 line-clamp-1">${sub.desc || 'Materi pembelajaran siap diakses.'}</p>
                                </div>
                            </div>

                            <!-- Tindakan berdasarkan peran -->
                            <div class="flex items-center gap-2">
                                ${teacherMode ? `
                                    <button onclick="openEditModal('${bab.id}', '${sub.id}')" class="p-1.5 rounded-lg bg-amber-500/10 text-amber-400 hover:bg-amber-500/20 transition" title="Edit sub-bab">
                                        <i class="fa-solid fa-pen text-xs"></i>
                                    </button>
                                ` : `
                                    <button onclick="openSubmitTaskModal('${sub.id}', '${sub.name}')" class="flex items-center gap-1 px-2 py-1.5 rounded-xl bg-brand-500/10 border border-brand-500/20 text-brand-400 hover:bg-brand-500 hover:text-white font-bold text-xs transition duration-300" title="Kirim Jawaban Tugas">
                                        <i class="fa-solid fa-paper-plane"></i> <span class="hidden sm:inline">Kirim Tugas</span>
                                    </button>
                                `}
                                <a href="${sub.link}" target="_blank" class="flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-slate-800 hover:bg-brand-600 hover:text-white border border-slate-700/80 text-slate-300 font-bold text-xs transition duration-300 shadow-md">
                                    <i class="fa-solid fa-arrow-up-right-from-square"></i>
                                    Akses
                                </a>
                            </div>
                        </div>
                    `;
                });

                cardHTML += `
                            </div>
                        </div>
                    </div>
                `;
                container.innerHTML += cardHTML;
            });
        }

        // Render rekap pengiriman tugas siswa
        function renderSubmissions() {
            const tableBody = document.getElementById('submissionsTableBody');
            if (!tableBody) return;

            tableBody.innerHTML = '';
            const selectedClass = document.getElementById('teacherClassFilter').value;

            const filteredSubmissions = studentSubmissions.filter(sub => {
                return selectedClass === 'all' || sub.studentClass === selectedClass;
            });

            if (filteredSubmissions.length === 0) {
                tableBody.innerHTML = `
                    <tr>
                        <td colspan="6" class="p-8 text-center text-slate-500 font-medium">
                            <i class="fa-regular fa-folder-open text-2xl block mb-2"></i> Belum ada jawaban siswa yang dikirimkan.
                        </td>
                    </tr>
                `;
                return;
            }

            filteredSubmissions.forEach(sub => {
                const statusBadge = sub.status === "Sudah Dinilai" 
                    ? `<span class="inline-flex items-center gap-1 px-2.5 py-1 rounded-full text-xs font-bold bg-emerald-500/10 text-emerald-400 border border-emerald-500/20"><i class="fa-solid fa-check"></i> Nilai: ${sub.score}</span>`
                    : `<span class="inline-flex items-center gap-1 px-2.5 py-1 rounded-full text-xs font-bold bg-amber-500/10 text-amber-400 border border-amber-500/20"><i class="fa-solid fa-circle-exclamation"></i> Belum Dinilai</span>`;

                const linkElement = sub.link 
                    ? `<a href="${sub.link}" target="_blank" class="text-brand-400 hover:underline flex items-center gap-1 text-xs"><i class="fa-solid fa-link"></i> Buka Lampiran</a>`
                    : `<span class="text-slate-600 text-xs italic">Tanpa Lampiran</span>`;

                tableBody.innerHTML += `
                    <tr class="hover:bg-slate-900/40 transition">
                        <td class="p-4 font-semibold text-white">
                            <div>${sub.studentName}</div>
                            <div class="text-[10px] text-slate-500">Kelas: ${sub.studentClass}</div>
                        </td>
                        <td class="p-4 text-xs max-w-xs truncate" title="${sub.subName}">
                            ${sub.subName}
                        </td>
                        <td class="p-4 text-xs text-slate-400">
                            ${sub.submittedAt}
                        </td>
                        <td class="p-4">
                            ${linkElement}
                        </td>
                        <td class="p-4">
                            ${statusBadge}
                        </td>
                        <td class="p-4 text-center">
                            <div class="flex justify-center gap-2">
                                <button onclick="openGradeModal('${sub.id}')" class="px-2.5 py-1.5 rounded-lg bg-emerald-600/10 hover:bg-emerald-600/20 text-emerald-400 font-semibold text-xs flex items-center gap-1.5 transition">
                                    <i class="fa-solid fa-graduation-cap"></i> Beri Nilai
                                </button>
                                <button onclick="deleteSubmission('${sub.id}')" class="p-1.5 rounded-lg bg-red-500/10 hover:bg-red-500/20 text-red-400 transition" title="Hapus Jawaban">
                                    <i class="fa-solid fa-trash-can text-xs"></i>
                                </button>
                            </div>
                        </td>
                    </tr>
                `;
            });
        }

        // Progres Tracker Siswa
        function toggleSubComplete(subId) {
            const index = completedSubs.indexOf(subId);
            if (index > -1) {
                completedSubs.splice(index, 1);
            } else {
                completedSubs.push(subId);
            }
            saveToLocalStorage();
            updateProgress();
            renderDashboard();
        }

        function updateProgress() {
            let totalSubCount = 0;
            informaticsData.forEach(bab => {
                totalSubCount += bab.subs.length;
            });

            const completedCount = completedSubs.length;
            const percentage = totalSubCount > 0 ? Math.round((completedCount / totalSubCount) * 100) : 0;

            document.getElementById('completedCount').innerText = completedCount;
            document.getElementById('totalCount').innerText = totalSubCount;
            document.getElementById('globalPercentText').innerText = percentage + "%";
            document.getElementById('globalProgressBar').style.width = percentage + "%";

            const circle = document.getElementById('progressCircle');
            const circumference = 2 * Math.PI * 16;
            const offset = circumference - (percentage / 100) * circumference;
            circle.style.strokeDasharray = `${circumference} ${circumference}`;
            circle.style.strokeDashoffset = offset;
        }

        // Pencarian Filter Realtime
        function filterContent() {
            const query = document.getElementById('searchInput').value.toLowerCase();
            const items = document.querySelectorAll('.sub-item');
            
            items.forEach(item => {
                const title = item.getAttribute('data-title');
                if (title.includes(query)) {
                    item.classList.remove('hidden');
                } else {
                    item.classList.add('hidden');
                }
            });
        }

        // Filter Tipe Kategori
        function filterType(type) {
            currentFilter = type;
            const buttons = document.querySelectorAll('.type-filter-btn');
            
            buttons.forEach(btn => {
                if (btn.innerText.includes(type === 'all' ? 'Semua' : type)) {
                    btn.className = "type-filter-btn px-4 py-2 rounded-xl text-xs sm:text-sm font-semibold bg-brand-600 text-white shadow-lg shadow-brand-500/20 whitespace-nowrap transition";
                } else {
                    btn.className = "type-filter-btn px-4 py-2 rounded-xl text-xs sm:text-sm font-medium bg-slate-800 text-slate-400 hover:text-white hover:bg-slate-700 whitespace-nowrap transition";
                }
            });

            renderDashboard();
        }

        // Tampilkan Notifikasi Toast
        function showToast(message) {
            const toast = document.getElementById('toast');
            const toastMsg = document.getElementById('toastMsg');
            toastMsg.innerText = message;
            
            toast.classList.remove('translate-y-12', 'opacity-0');
            toast.classList.add('translate-y-0', 'opacity-100');
            
            setTimeout(() => {
                toast.classList.remove('translate-y-0', 'opacity-100');
                toast.classList.add('translate-y-12', 'opacity-0');
            }, 3000);
        }

        // Buka Modal Edit Sub-Bab (Mode Guru)
        function openEditModal(babId, subId) {
            const bab = informaticsData.find(b => b.id === babId);
            const sub = bab.subs.find(s => s.id === subId);

            selectedSubToEdit = { babId, subId };

            document.getElementById('editSubName').value = sub.name;
            document.getElementById('editSubCategory').value = sub.cat;
            document.getElementById('editSubDuration').value = sub.duration;
            document.getElementById('editSubLink').value = sub.link;
            document.getElementById('editSubDesc').value = sub.desc || '';

            document.getElementById('editModal').classList.remove('hidden');
        }

        function closeEditModal() {
            document.getElementById('editModal').classList.add('hidden');
            selectedSubToEdit = null;
        }

        function saveEditData() {
            if (!selectedSubToEdit) return;

            const { babId, subId } = selectedSubToEdit;
            const bab = informaticsData.find(b => b.id === babId);
            const sub = bab.subs.find(s => s.id === subId);

            sub.name = document.getElementById('editSubName').value;
            sub.cat = document.getElementById('editSubCategory').value;
            sub.duration = document.getElementById('editSubDuration').value;
            sub.link = document.getElementById('editSubLink').value;
            sub.desc = document.getElementById('editSubDesc').value;

            saveToLocalStorage();
            renderDashboard();
            updateProgress();
            closeEditModal();
            showToast("Perubahan sub-bab berhasil disimpan!");
        }

        // ================= SISWA: SUBMIT TUGAS =================

        function openSubmitTaskModal(subId, subName) {
            selectedSubToSubmit = { subId, subName };
            document.getElementById('submitModalSubTitle').innerText = subName;
            
            document.getElementById('studentNameInput').value = '';
            document.getElementById('studentNotesInput').value = '';
            document.getElementById('studentLinkInput').value = '';

            document.getElementById('submitTaskModal').classList.remove('hidden');
        }

        function closeSubmitTaskModal() {
            document.getElementById('submitTaskModal').classList.add('hidden');
            selectedSubToSubmit = null;
        }

        function submitStudentTask() {
            const name = document.getElementById('studentNameInput').value.trim();
            const kelas = document.getElementById('studentClassInput').value;
            const notes = document.getElementById('studentNotesInput').value.trim();
            const link = document.getElementById('studentLinkInput').value.trim();

            if (!name) {
                showToast("Harap masukkan Nama Lengkap Anda!");
                return;
            }
            if (!notes) {
                showToast("Harap berikan keterangan atau jawaban tugas!");
                return;
            }

            const now = new Date();
            const timestamp = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;

            const newSubmission = {
                id: "sub_" + Date.now(),
                studentName: name,
                studentClass: kelas,
                subId: selectedSubToSubmit.subId,
                subName: selectedSubToSubmit.subName,
                notes: notes,
                link: link,
                submittedAt: timestamp,
                status: "Belum Dinilai",
                score: "",
                feedback: ""
            };

            studentSubmissions.unshift(newSubmission);
            saveToLocalStorage();
            
            if (!completedSubs.includes(selectedSubToSubmit.subId)) {
                completedSubs.push(selectedSubToSubmit.subId);
            }
            
            updateProgress();
            renderDashboard();
            renderSubmissions();
            closeSubmitTaskModal();
            showToast("Jawaban tugas Anda berhasil dikirimkan ke Guru!");
        }

        // ================= GURU: BERI NILAI =================

        function openGradeModal(submissionId) {
            const submission = studentSubmissions.find(s => s.id === submissionId);
            if (!submission) return;

            selectedSubmissionToGrade = submission;

            document.getElementById('gradeModalStudentName').innerText = submission.studentName;
            document.getElementById('gradeModalClass').innerText = submission.studentClass;
            document.getElementById('gradeModalDate').innerText = submission.submittedAt;
            document.getElementById('gradeModalSubName').innerText = submission.subName;
            document.getElementById('gradeModalResponseText').innerText = submission.notes;

            document.getElementById('gradeScoreInput').value = submission.score;
            document.getElementById('gradeFeedbackInput').value = submission.feedback || '';

            document.getElementById('gradeModal').classList.remove('hidden');
        }

        function closeGradeModal() {
            document.getElementById('gradeModal').classList.add('hidden');
            selectedSubmissionToGrade = null;
        }

        function saveStudentGrade() {
            if (!selectedSubmissionToGrade) return;

            const score = document.getElementById('gradeScoreInput').value.trim();
            const feedback = document.getElementById('gradeFeedbackInput').value.trim();

            if (score === "" || isNaN(score) || score < 0 || score > 100) {
                showToast("Masukkan nilai valid antara 0 s.d. 100!");
                return;
            }

            selectedSubmissionToGrade.score = score;
            selectedSubmissionToGrade.feedback = feedback;
            selectedSubmissionToGrade.status = "Sudah Dinilai";

            saveToLocalStorage();
            renderSubmissions();
            renderDashboard();
            closeGradeModal();
            showToast(`Siswa ${selectedSubmissionToGrade.studentName} berhasil dinilai: ${score}!`);
        }

        function deleteSubmission(submissionId) {
            studentSubmissions = studentSubmissions.filter(s => s.id !== submissionId);
            saveToLocalStorage();
            renderSubmissions();
            renderDashboard();
            showToast("Data pengiriman siswa telah dihapus.");
        }

        // ================= IMPOR/EKSPOR DATA GURU =================

        function exportData() {
            const dataToExport = {
                informaticsData: informaticsData,
                studentSubmissions: studentSubmissions
            };
            const dataStr = JSON.stringify(dataToExport, null, 2);
            const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr);
            
            const exportFileDefaultName = 'materi-dan-jawaban-informatika.json';
            
            const linkElement = document.createElement('a');
            linkElement.setAttribute('href', dataUri);
            linkElement.setAttribute('download', exportFileDefaultName);
            linkElement.click();
            showToast("Semua data materi & jawaban siswa berhasil diunduh!");
        }

        function triggerImport() {
            document.getElementById('importFileInput').click();
        }

        function importData(event) {
            const file = event.target.files[0];
            if (!file) return;

            const reader = new FileReader();
            reader.onload = function(e) {
                try {
                    const parsedData = JSON.parse(e.target.result);
                    if (parsedData.informaticsData && parsedData.studentSubmissions) {
                        informaticsData = parsedData.informaticsData;
                        studentSubmissions = parsedData.studentSubmissions;
                    } else if (Array.isArray(parsedData)) {
                        informaticsData = parsedData;
                    } else {
                        showToast("Format file salah. Gunakan file ekspor dari sistem ini.");
                        return;
                    }
                    saveToLocalStorage();
                    renderDashboard();
                    updateProgress();
                    renderSubmissions();
                    showToast("Semua data materi dan jawaban siswa berhasil diimpor!");
                } catch (error) {
                    showToast("Gagal membaca file konfigurasi.");
                }
            };
            reader.readAsText(file);
        }
    </script>
</body>
</html>

Tentu! Saya telah menambahkan mekanisme keamanan khusus menggunakan kata sandi 5678 untuk masuk ke Mode Guru.

Kode Akses Siswa (12345): Siswa wajib memasukkan kode 12345



MPLS

Ide ini sangat cocok untuk MPLS karena interaktif dan membuat peserta berpikir logis. Konsepnya mirip "Defuse the Bomb Game", tetapi versi edukasi menggunakan Arduino Uno.

Konsep Permainan

Peserta melihat ada 2 kabel:

  • 🟢 Hijau = kabel aman (harus dicabut)

  • 🔴 Merah = kabel jebakan (jika dicabut buzzer berbunyi)

Aturan:

  • Saat permainan dimulai buzzer diam.

  • Jika kabel hijau dicabut → muncul suara pendek sebagai tanda berhasil (opsional) atau LED hijau menyala.

  • Jika kabel merah dicabut → buzzer berbunyi terus.


Komponen

JumlahKomponen
1Arduino Uno
1Buzzer Active 5V
2Push Button / Kabel jumper sebagai saklar
2Resistor 10K
1LED Hijau
1LED Merah
2Resistor 220Ω

Cara Kerja Kabel

Kabel sebenarnya bukan benar-benar dipotong.

Gunakan jumper sebagai "kabel".

Saat kabel masih terpasang:
Arduino membaca HIGH.

Saat kabel dicabut:
Arduino membaca LOW.


Skema Wiring

                +5V
                 |
                 |
        -------------------
        |                 |
     Kabel Hijau      Kabel Merah
        |                 |
       D2               D3
        |                 |
      10KΩ             10KΩ
        |                 |
       GND              GND



LED Hijau
D8 ----220Ω---->|-----GND

LED Merah
D9 ----220Ω---->|-----GND

Buzzer
D10 ---------- (+)
               (-)
               |
              GND

Skema Lebih Mudah

      +5V
       |
     Kabel
       |
Arduino Pin
       |
   10K Resistor
       |
      GND

Saat kabel dicabut:

Pin turun menjadi LOW.

Arduino tahu kabel telah dilepas.


Program Arduino

//========================================
// GAME TEBAK KABEL
//========================================

const int kabelHijau = 2;
const int kabelMerah = 3;

const int buzzer = 10;

const int ledHijau = 8;
const int ledMerah = 9;

void setup() {

  pinMode(kabelHijau, INPUT);

  pinMode(kabelMerah, INPUT);

  pinMode(buzzer, OUTPUT);

  pinMode(ledHijau, OUTPUT);

  pinMode(ledMerah, OUTPUT);

  digitalWrite(buzzer, LOW);
}

void loop() {

  int hijau = digitalRead(kabelHijau);

  int merah = digitalRead(kabelMerah);

  //=========================
  // Kabel Merah Dicabut
  //=========================

  if (merah == LOW) {

    digitalWrite(ledMerah, HIGH);

    tone(buzzer, 1000);

    while (1);

  }

  //=========================
  // Kabel Hijau Dicabut
  //=========================

  if (hijau == LOW) {

    digitalWrite(ledHijau, HIGH);

    tone(buzzer, 2000);

    delay(200);

    noTone(buzzer);

    while (1);

  }

}

Menggunakan Internal Pull-up (Lebih Sederhana)

Anda bahkan tidak perlu resistor 10K. Gunakan INPUT_PULLUP sehingga rangkaian lebih sederhana.

Wiring

D2 -------- Kabel Hijau -------- GND

D3 -------- Kabel Merah -------- GND

Saat kabel masih terhubung ke GND:

LOW

Saat kabel dicabut:

HIGH

Kode menjadi:

pinMode(kabelHijau, INPUT_PULLUP);
pinMode(kabelMerah, INPUT_PULLUP);

Kemudian logikanya dibalik:

if (digitalRead(kabelMerah) == HIGH)

artinya kabel merah telah dicabut.


Versi yang Lebih Menarik untuk MPLS

Supaya lebih seru, tambahkan:

  • ⏳ Timer 30 detik (LCD/OLED menampilkan hitung mundur).

  • 🔊 Modul suara DFPlayer Mini dengan efek "Boom!" saat gagal.

  • 💡 LED RGB sebagai indikator status.

  • 🎵 Musik latar selama permainan berlangsung.

  • 🔢 Layar OLED 0,96 inci untuk menampilkan "Pilih kabel yang benar!".

  • 🔄 Tombol Reset untuk memulai permainan berikutnya.

  • 🎲 Pilihan kabel aman bisa diacak setiap kali alat dinyalakan, sehingga peserta tidak bisa menebak berdasarkan giliran sebelumnya.

Skema Konsep Keseluruhan

                +----------------------+
                |     Arduino UNO      |
                |                      |
 Kabel Hijau -->| D2                   |
 Kabel Merah -->| D3                   |
                |                      |
 LED Hijau ---->| D8                   |
 LED Merah ---->| D9                   |
 Buzzer ------->| D10                  |
 Tombol Reset ->| D4                   |
                +----------------------+

Untuk acara MPLS, saya juga bisa membantu membuat versi yang lebih profesional dengan kotak berbentuk bom menggunakan akrilik, lengkap dengan OLED countdown, efek suara, lampu berkedip, dan pengacakan kabel otomatis, sehingga tampilannya lebih menarik dan peserta tidak bisa menghafal jawaban.

Karena ini untuk MPLS (Masa Pengenalan Lingkungan Sekolah), saya menyarankan materi dibuat fun, interaktif, dan memotivasi, bukan hanya mengajarkan Arduino. Tujuan utamanya adalah membuat siswa baru merasa bahwa belajar di jurusan teknik itu seru.


🎮 MPLS 2026

MISSION IMPOSSIBLE

Defuse The Bomb with Arduino Uno

"Berpikir Logis Sebelum Bertindak"


Slide 1

Selamat Datang

🚀 Mission Impossible

Hari ini kalian bukan hanya menjadi peserta MPLS.

Hari ini kalian adalah...

🛠️ Teknisi

🤖 Programmer

⚡ Engineer

🧠 Problem Solver

Tugas kalian hanya satu...

Selamatkan sekolah dari bom digital!


Slide 2

Cerita Permainan

Bayangkan...

Sebuah bom telah dipasang di sekolah.

Bom tersebut tidak bisa dijinakkan oleh polisi.

Tidak bisa dijinakkan oleh tentara.

Tetapi...

Hanya bisa dijinakkan oleh siswa SMK!

Mengapa?

Karena bom menggunakan sistem Arduino.


Slide 3

Tantangan

Di depan kalian terdapat dua kabel.

🟢 Hijau

🔴 Merah

Hanya satu kabel yang benar.

Jika salah...

💥

Alarm akan berbunyi.


Slide 4

Sebelum Memilih

Jangan asal menebak.

Di dunia teknik...

Kesalahan kecil dapat menyebabkan:

❌ Mesin rusak

❌ Program error

❌ Robot gagal

❌ Sistem berhenti

Karena itu...

Teknisi selalu berpikir sebelum bertindak.


Slide 5

Apa Itu Arduino?

Arduino adalah sebuah papan mikrokontroler.

Arduino dapat:

✔ Menyalakan lampu

✔ Menggerakkan robot

✔ Mengontrol mesin

✔ Membaca sensor

✔ Mengendalikan kendaraan otomatis

Semua itu dilakukan dengan sebuah program.


Slide 6

Mengapa Belajar Arduino?

Karena hampir semua teknologi modern menggunakannya.

Contohnya:

🚗 Mobil listrik

🤖 Robot industri

🏠 Smart Home

🚜 Pertanian otomatis

🚦 Lampu lalu lintas pintar

🚁 Drone


Slide 7

Arduino Ada di Mana?

Tanyakan kepada peserta:

"Menurut kalian Arduino dipakai di mana?"

Biarkan mereka menjawab.

Kemudian tampilkan gambar:

  • Robot

  • Mobil

  • Lift

  • ATM

  • Mesin kopi

  • Pintu otomatis

Lalu katakan:

Semua menggunakan sistem kontrol yang prinsipnya sama.


Slide 8

Cara Kerja Permainan

Arduino selalu membaca kondisi kabel.

Jika:

Hijau dicabut

↓

Arduino membaca

↓

Program memutuskan

↓

LED Hijau menyala

↓

Misi berhasil


Jika kabel merah dicabut

↓

Arduino membaca

↓

Program menjalankan alarm

↓

Buzzer berbunyi

↓

Mission Failed


Slide 9

Bagaimana Arduino Berpikir?

Arduino tidak bisa berpikir.

Arduino hanya menjalankan logika.

Contohnya:

IF kabel merah dicabut

THEN

Buzzer ON

atau

IF kabel hijau dicabut

THEN

LED Hijau ON

Inilah yang disebut algoritma.


Slide 10

Tantangan untuk Peserta

Siapa yang berani maju?

Satu orang.

Tidak boleh berdiskusi.

Tidak boleh bertanya.

Harus percaya diri.

Silakan pilih kabel.


Slide 11

Setelah Alarm Berbunyi

Tanyakan kepada peserta:

Mengapa gagal?

Biasanya mereka menjawab:

"Salah pilih."

Jawab:

Benar.

Di dunia teknologi...

Kesalahan kecil saja bisa menyebabkan kerugian besar.

Karena itu seorang engineer harus:

✔ Teliti

✔ Berani mencoba

✔ Tidak panik

✔ Berpikir logis


Slide 12

Rahasia Engineer

Seorang programmer hebat bukan yang tidak pernah salah.

Tetapi...

Yang mau belajar dari kesalahan.

Karena setiap robot yang hebat...

Berawal dari ribuan percobaan.


Slide 13

Tahukah Kalian?

Robot yang digunakan di pabrik mobil...

Diprogram menggunakan logika.

Drone...

Menggunakan sensor.

Mobil listrik...

Menggunakan mikrokontroler.

Semuanya dipelajari mulai dari Arduino.


Slide 14

Di Jurusan Ini Kalian Akan Belajar

⚡ Elektronika

🤖 Robotika

💻 Pemrograman

🔧 Otomotif Modern

🌐 Internet of Things (IoT)

📡 Sensor

📱 Smart Device


Slide 15

Game Kedua (Opsional)

Tambahkan 5 kabel.

Merah

Hijau

Biru

Kuning

Putih

Setiap permainan posisi kabel aman diacak menggunakan program Arduino.

Dengan demikian tidak ada peserta yang bisa menebak berdasarkan giliran sebelumnya.


Slide 16

Tantangan Bonus

Buat peserta menebak:

Menurut kalian...

Mengapa komputer tidak pernah bosan?

Jawaban:

Karena komputer hanya melakukan apa yang kita program.


Slide 17

Motivasi

Hari ini kalian hanya melihat dua kabel.

Tiga tahun lagi...

Kalian bisa membuat:

🤖 Robot

🚗 Mobil listrik

🏭 Mesin otomatis

🌾 Smart Farming

🏠 Smart Home

🚁 Drone


Slide 18

Penutup

"Teknologi tidak diciptakan oleh orang yang paling pintar.

Tetapi oleh orang yang mau terus belajar."

Selamat datang di dunia teknologi.

Selamat datang di dunia robotika.

Selamat datang di SMK.


🎁 Agar lebih spektakuler saat MPLS

Saya juga menyarankan menambahkan beberapa efek agar peserta semakin antusias:

  • ⏱️ Countdown 30 detik dengan display OLED atau 7-segment sehingga peserta merasa dikejar waktu.

  • 🔊 Efek suara seperti hitung mundur dan ledakan menggunakan modul DFPlayer Mini.

  • 🚨 Lampu strobo merah-biru yang berkedip saat peserta gagal.

  • 🎵 Musik latar ala film Mission Impossible selama permainan berlangsung.

  • 🧳 Kotak bom dari akrilik atau box hitam dengan stiker "DANGER", "AUTHORIZED PERSONNEL ONLY", dan logo sekolah.

  • 🧑‍🎤 Ajak 2–3 peserta sekaligus agar suasana lebih kompetitif dan beri hadiah kecil bagi yang berhasil.

Dengan konsep ini, sesi MPLS akan terasa seperti edutainment: siswa bermain, tertawa, sekaligus belajar dasar logika pemrograman dan mengenal Arduino sebagai teknologi yang akan mereka pelajari di SMK.

Ini ide yang sangat menarik. Anda bisa membuat pengalaman MPLS seperti Escape Room atau Mission Impossible, sehingga siswa tidak langsung bermain tebak kabel. Mereka harus menyelesaikan misi secara bertahap.

Alur yang saya sarankan:

Level 1: Login ke Portal Agen → Level 2: Pecahkan Kode Rahasia → Level 3: Masuk ke Ruang Bom → Level 4: Tebak Kabel Arduino → Level 5: Mission Complete

Hal ini akan membuat siswa lebih penasaran dan terlibat.

Konsep Halaman HTML

+------------------------------------------------+
|              AVENTRON ROBOTICS                 |
|         SECRET ENGINEERING PORTAL              |
+------------------------------------------------+

        ███ ACCESS TERMINAL ███

        Nama Agen :
        [________________]

        Kode Misi :
        [________________]

             [ LOGIN ]

----------------------------------------------
STATUS : Menunggu autentikasi...

Jika login berhasil, muncul animasi:

ACCESS GRANTED

Loading...

Decrypting Mission....

██████████████████

Mission Level 1

Level 1 – Pecahkan Password

Layar menampilkan:

========================================

LEVEL 1

PASSWORD ENCRYPTED

A = 1
B = 2
C = 3

Jika

ROBOT

bernilai...

18 15 2 15 20

Maka

ARDUINO

= ?

__________________

[ KIRIM ]

Jika benar muncul:

ACCESS GRANTED

Level 2 – Logika

Sebuah lampu mati.

Saklar OFF.

Apa yang harus dilakukan?

○ Menunggu

○ Menyalakan Saklar

○ Memukul Lampu

Jika memilih benar

↓

lanjut.


Level 3 – Tebak Arduino

Muncul gambar Arduino.

Pertanyaan:

Komponen ini bernama?

○ Raspberry Pi

○ Arduino Uno

○ Laptop

○ Powerbank

Level 4

WARNING

BOMB DETECTED

ONLY ENGINEER CAN DEFUSE

PRESS START

Tombol

START MISSION

↓

baru menuju meja Arduino.


Agar terlihat profesional

Saya akan membuat tampilannya seperti:

✔ Film Hacker

✔ Matrix

✔ Mission Impossible

✔ Cyber Security

✔ Animasi terminal

✔ Suara beep

✔ Progress bar

✔ Fullscreen

✔ Dark Mode


Fitur yang akan dibuat

✅ Background animasi Matrix

✅ Terminal hacker

✅ Efek mengetik

✅ Suara komputer

✅ Progress loading

✅ Timer

✅ Login

✅ 5 level

✅ Skor

✅ Nama peserta

✅ Leaderboard

✅ QR Code hasil

✅ Responsive HP

✅ Bisa dijalankan offline


Saya bahkan menyarankan menggunakan alur berikut untuk MPLS:

LOGIN
   │
   ▼
SCAN QR
   │
   ▼
LEVEL 1
Pecahkan Password
   │
   ▼
LEVEL 2
Tebak Logika
   │
   ▼
LEVEL 3
Mengenal Arduino
   │
   ▼
LEVEL 4
Countdown 30 Detik
   │
   ▼
LEVEL 5
Defuse The Bomb
(Tebak Kabel Arduino)
   │
   ▼
MISSION COMPLETE

Saran tambahan agar semakin berkesan

Karena ini akan menjadi acara MPLS, saya menyarankan membuatnya sebagai website mini satu halaman (single-page web app) dengan nuansa Mission Impossible dan identitas Aventron Robotics Academy. Di dalamnya bisa ada:

  • 🎬 Intro sinematik dengan animasi "Mission Briefing".

  • 💻 Efek terminal hacker lengkap dengan suara "access granted" dan "access denied".

  • 🧩 5–10 level teka-teki yang semakin sulit.

  • ⏱️ Countdown timer untuk menambah ketegangan.

  • 🏆 Skor akhir dan sertifikat digital "Agent Certified" yang menampilkan nama peserta.

  • 📱 Dapat dijalankan 100% offline hanya dengan membuka file index.html di browser, tanpa instalasi atau internet.

Dengan konsep seperti ini, siswa akan merasa sedang mengikuti escape room digital, bukan sekadar presentasi MPLS. Ini biasanya jauh lebih efektif untuk menarik minat mereka terhadap pemrograman, Arduino, dan robotika.

portal 

<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MISSION IMPOSSIBLE - Arduino Challenge</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        body { background: #050505; color: #00ff00; font-family: 'Courier New', Courier, monospace; }
        .glitch-shadow { box-shadow: 0 0 15px rgba(0, 255, 0, 0.3); }
        .level { display: none; }
        .active { display: block; }
    </style>
</head>
<body class="flex items-center justify-center min-h-screen p-4">

    <div id="game-container" class="w-full max-w-lg border-2 border-green-500 p-8 rounded-xl bg-gray-900 glitch-shadow">
        <h1 class="text-3xl font-bold text-center mb-2 tracking-widest uppercase">Mission Impossible</h1>
       
        <!-- Timer -->
        <div id="timer-box" class="hidden text-center text-red-500 font-bold text-xl mb-4 border border-red-500 py-1">
            WAKTU: <span id="time">35</span> DETIK
        </div>

        <!-- Login -->
        <div id="login" class="level active">
            <h2 class="text-xl mb-4 text-center text-green-400">INPUT IDENTITAS AGEN</h2>
            <input id="nama" class="w-full bg-black border border-green-600 p-3 text-green-400 outline-none focus:border-green-300" placeholder="Masukkan Nama Sandi...">
            <button onclick="login()" class="w-full mt-4 bg-green-700 hover:bg-green-600 p-3 font-bold transition">MASUK KE SISTEM</button>
        </div>

        <!-- Level 1 -->
        <div id="level1" class="level">
            <h2 class="text-2xl mb-2 text-yellow-500">LEVEL 1: Keamanan Dasar</h2>
            <p id="math-text" class="mb-4">Selesaikan kalkulasi: 10 + 30 - 7 = ?</p>
            <input id="pin" type="number" class="w-full bg-black border border-green-600 p-3 text-green-400" placeholder="Jawaban...">
            <button onclick="cek1()" class="w-full mt-4 bg-green-700 hover:bg-green-600 p-3 font-bold">VERIFIKASI</button>
        </div>

        <!-- Level 2 -->
        <div id="level2" class="level">
            <h2 class="text-2xl mb-2 text-yellow-500">LEVEL 2: Logika Sirkuit</h2>
            <p class="mb-4">Jika LED belum menyala, apa langkah yang paling logis?</p>
            <div class="space-y-2">
                <button onclick="cek2(1)" class="w-full border border-green-600 p-2 hover:bg-green-900 transition">A. Menunggu saja</button>
                <button onclick="cek2(2)" class="w-full border border-green-600 p-2 hover:bg-green-900 transition">B. Menyalakan LED (Kode/Power)</button>
                <button onclick="cek2(3)" class="w-full border border-green-600 p-2 hover:bg-green-900 transition">C. Memukul Arduino</button>
            </div>
        </div>

        <!-- Level 2.5 -->
        <div id="level2_5" class="level">
            <h2 class="text-2xl mb-2 text-yellow-500">LEVEL 2.5: Identitas Pimpinan</h2>
            <p class="mb-4">Siapakah nama Kepala Sekolah kita?</p>
            <input id="jawabanKepala" type="text" class="w-full bg-black border border-green-600 p-3 text-green-400" placeholder="Nama Kepala Sekolah...">
            <button onclick="cek2_5()" class="w-full mt-4 bg-green-700 hover:bg-green-600 p-3 font-bold">VERIFIKASI NAMA</button>
            <p id="hintTebak" class="mt-2 text-sm text-gray-400"></p>
        </div>

        <!-- Level 3 -->
        <div id="level3" class="level">
            <h2 class="text-2xl mb-2 text-yellow-500">LEVEL 3: Identifikasi Perangkat</h2>
            <p class="mb-4">Apa nama papan mikrokontroler paling populer untuk pemula?</p>
            <input id="jawab" class="w-full bg-black border border-green-600 p-3 text-green-400" placeholder="Nama Perangkat...">
            <button onclick="cek3()" class="w-full mt-4 bg-green-700 hover:bg-green-600 p-3 font-bold">SUBMIT KODE</button>
        </div>

        <!-- Finish -->
        <div id="finish" class="level text-center">
            <h1 class="text-4xl text-green-500 font-bold mb-4">MISSION COMPLETE</h1>
            <p id="peserta" class="text-xl mb-6"></p>
            <div class="p-4 border-2 border-yellow-500 text-yellow-500 animate-pulse">
                SELAMAT! SILAKAN MENUJU MEJA ARDUINO UNTUK MENJINAKKAN BOM!
            </div>
        </div>
    </div>

    <script>
        let namaPeserta = "";
        let level1Attempt = 0;
        let timeLeft = 35;
        let timerId = null;

        function startTimer() {
            document.getElementById("timer-box").classList.remove('hidden');
            timeLeft = 35;
            document.getElementById("time").innerText = timeLeft;
           
            clearInterval(timerId);
            timerId = setInterval(() => {
                timeLeft--;
                document.getElementById("time").innerText = timeLeft;
                if (timeLeft <= 0) {
                    clearInterval(timerId);
                    alert("WAKTU HABIS! Misi Gagal.");
                    location.reload();
                }
            }, 1000);
        }

        function switchLevel(hideId, showId) {
            document.getElementById(hideId).classList.remove('active');
            document.getElementById(showId).classList.add('active');
        }

        function login() {
            let nama = document.getElementById("nama").value;
            if(!nama) return alert("Identitas wajib diisi, Agen!");
            namaPeserta = nama;
            switchLevel("login", "level1");
            startTimer();
        }

        function cek1() {
            let val = document.getElementById("pin").value;
            if(level1Attempt === 0) {
                if(val == "33") {
                    switchLevel("level1", "level2");
                } else {
                    level1Attempt++;
                    document.getElementById("math-text").innerText = "Gagal! Akses keamanan diperketat. Selesaikan: 50 - 23 + 34 - 5 = ?";
                    alert("PIN Salah! Akses diperketat.");
                }
            } else {
                if(val == "56") {
                    switchLevel("level1", "level2");
                } else {
                    alert("Akses Ditolak Permanen! Misi Gagal.");
                    location.reload();
                }
            }
        }

        function cek2(x) {
            if(x == 2) {
                switchLevel("level2", "level2_5");
            } else {
                alert("Tindakan Tidak Efektif. Ulangi!");
            }
        }

        function cek2_5() {
            let tebakan = document.getElementById("jawabanKepala").value.toUpperCase();
            if(tebakan === "MUSLI") {
                alert("Nama Terkonfirmasi! Sistem Terbuka.");
                switchLevel("level2_5", "level3");
            } else {
                document.getElementById("hintTebak").innerText = "NAMA SALAH! Otoritas tidak dikenal.";
                document.getElementById("hintTebak").classList.add("text-red-500");
            }
        }

        function cek3() {
            let j = document.getElementById("jawab").value.toUpperCase();
            if(j.includes("ARDUINO")) {
                clearInterval(timerId);
                document.getElementById("timer-box").classList.add('hidden');
                document.getElementById("peserta").innerText = "AGEN : " + namaPeserta;
                switchLevel("level3", "finish");
            } else {
                alert("Kode Salah!");
            }
        }
    </script>
</body>
</html>

rakit

Bagus, sekarang proyek mulai berkembang. Saya sarankan kita tetap bertahap, jadi LCD hanya digunakan untuk menampilkan status permainan terlebih dahulu, belum memakai timer.

===============================================================

Dari foto yang Anda kirim, saya melihat Anda menggunakan:

  • Arduino Uno

  • Breadboard

  • 3 LED (Hijau, Merah, Kuning)

  • Resistor

  • Kabel jumper

Untuk proyek MPLS "Penjinakan Bom", cara yang paling mudah dan stabil adalah menggunakan 3 kabel (sebagai sensor).

Cara Kerja

Ketika ketiga kabel masih terhubung:

  • LED Mati

Jika salah satu kabel dilepas (misalnya Kabel 3):

  • LED Merah menyala

  • (Nanti bisa ditambah buzzer)

Prinsipnya menggunakan INPUT_PULLUP, sehingga tidak perlu resistor 10K lagi.


Rangkaian

Misalkan menggunakan:

KabelArduino
Kabel 1D2
Kabel 2D3
Kabel 3D4

Semua ujung kabel satunya lagi disatukan ke GND.

Jadi seperti ini

Arduino D2 -------- Kabel 1 -------- GND

Arduino D3 -------- Kabel 2 -------- GND

Arduino D4 -------- Kabel 3 -------- GND

Selama kabel masih terpasang

D2 = LOW
D3 = LOW
D4 = LOW

Begitu Kabel 3 dicabut

D4 = HIGH

Arduino langsung tahu kabel diputus.


LED

Misalkan

LED Hijau  -> D8
LED Merah  -> D9
LED Kuning -> D10

Anoda LED → Pin Arduino melalui resistor 220 Ω.

Katoda LED → GND.


Program

//=====================
// Kabel
//=====================
const int kabel1 = 2;
const int kabel2 = 3;
const int kabel3 = 4;

//=====================
// LED
//=====================
const int ledHijau = 8;
const int ledMerah = 9;
const int ledKuning = 10;

void setup()
{
  pinMode(kabel1, INPUT_PULLUP);
  pinMode(kabel2, INPUT_PULLUP);
  pinMode(kabel3, INPUT_PULLUP);

  pinMode(ledHijau, OUTPUT);
  pinMode(ledMerah, OUTPUT);
  pinMode(ledKuning, OUTPUT);

  digitalWrite(ledHijau, HIGH);
  digitalWrite(ledMerah, LOW);
  digitalWrite(ledKuning, LOW);
}

void loop()
{
  if (digitalRead(kabel3) == HIGH)
  {
    digitalWrite(ledHijau, LOW);
    digitalWrite(ledMerah, HIGH);
    digitalWrite(ledKuning, HIGH);
  }
  else
  {
    digitalWrite(ledHijau, HIGH);
    digitalWrite(ledMerah, LOW);
    digitalWrite(ledKuning, LOW);
  }
}

Jika ingin kabel mana saja diputus langsung alarm

if (digitalRead(kabel1) == HIGH ||
    digitalRead(kabel2) == HIGH ||
    digitalRead(kabel3) == HIGH)
{
    digitalWrite(ledHijau, LOW);
    digitalWrite(ledMerah, HIGH);
}
else
{
    digitalWrite(ledHijau, HIGH);
    digitalWrite(ledMerah, LOW);
}

Kalau hanya Kabel 2 yang benar dipotong

Misalnya:

  • Hijau = Salah

  • Merah = Benar

  • Kuning = Salah

Maka logikanya:

Cabut Hijau  -> Gagal
Cabut Kuning -> Gagal
Cabut Merah  -> Berhasil

Ini lebih seru untuk game penjinakan bom.


Saya juga bisa membuat versi yang lebih menarik untuk MPLS

  • 💣 LCD 16x2 menampilkan "BOM AKTIF"

  • ⏱️ Hitung mundur 30 detik

  • 🔊 Buzzer berbunyi semakin cepat mendekati nol

  • 💡 LED berkedip seperti bom sungguhan

  • 🎮 Ada 3 kabel (Merah, Hijau, Kuning) dan hanya 1 kabel yang benar untuk diputus

  • 🏆 Jika salah kabel diputus → tulisan "BOOM!! Misi Gagal"

  • ✅ Jika benar → "Misi Berhasil"

Versi ini sangat cocok digunakan sebagai permainan interaktif saat kegiatan MPLS.

================================

Post a Comment

1 Comments

  1. https://gamma.app/docs/Generasi-Cerdas-Aman-dan-Bertanggung-Jawab-di-Era-Digital-qgldq2e7zha9z8l

    ReplyDelete