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

Post a Comment

0 Comments