// Deklarasi ekstraksi React Hooks di baris paling atas
const { useState, useEffect, useMemo } = React;
const API_URL = "api.php";
const INITIAL_CLASSES = [
{ id: 1, nama: 'Kelas 1 MI', fase: 'Fase A' },
{ id: 2, nama: 'Kelas 2 MI', fase: 'Fase A' },
{ id: 3, nama: 'Kelas 3 MI', fase: 'Fase B' },
{ id: 4, nama: 'Kelas 4 MI', fase: 'Fase B' },
{ id: 5, nama: 'Kelas 5 MI', fase: 'Fase C' },
{ id: 6, nama: 'Kelas 6 MI', fase: 'Fase C' },
];
function App() {
const [theme, setTheme] = useState('light');
const [isSidebarOpen, setIsSidebarOpen] = useState(true);
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [classes] = useState(INITIAL_CLASSES);
const [babList, setBabList] = useState([]);
const [subBabList, setSubBabList] = useState([]);
const [materiList, setMateriList] = useState([]);
const [loading, setLoading] = useState(true);
const [adminLogs, setAdminLogs] = useState([
{ waktu: '2026-06-28 09:00', aksi: 'Sistem Akidah Akhlak MI Kurikulum Berbasis Cinta (KBC) siap di cPanel.', user: 'Sistem' }
]);
const [currentView, setCurrentView] = useState('home');
const [selectedClass, setSelectedClass] = useState(null);
const [selectedBab, setSelectedBab] = useState(null);
const [selectedSubBab, setSelectedSubBab] = useState(null);
const [selectedMateri, setSelectedMateri] = useState(null);
const [searchQuery, setSearchQuery] = useState('');
const [adminActiveTab, setAdminActiveTab] = useState('materi');
const [editingBabId, setEditingBabId] = useState(null);
const [editingBabName, setEditingBabName] = useState('');
const [editingBabNomor, setEditingBabNomor] = useState(1);
const [selectedAdminClassId, setSelectedAdminClassId] = useState(1);
const [editingSubBabId, setEditingSubBabId] = useState(null);
const [editingSubBabName, setEditingSubBabName] = useState('');
const [editingSubBabNomor, setEditingSubBabNomor] = useState(1);
const [selectedAdminBabId, setSelectedAdminBabId] = useState(1);
const [formMode, setFormMode] = useState('add');
const [materiForm, setMateriForm] = useState({
id: null, class_id: 1, bab_id: 1, sub_bab_id: 1,
judul: '', konten: '', gambar: '', pdf_nama: '',
video_url: '', youtube_url: '', penulis: ''
});
const [showLoginModal, setShowLoginModal] = useState(false);
const [loginForm, setLoginForm] = useState({ username: '', password: '' });
const [loginError, setLoginError] = useState('');
const [toast, setToast] = useState({ show: false, message: '', type: 'success' });
const [isPreviewFormMode, setIsPreviewFormMode] = useState(false);
const loadDatabaseFromMySQL = async () => {
setLoading(true);
try {
const response = await fetch(`${API_URL}?action=get_data`);
const data = await response.json();
if (data.status === 'success') {
setBabList(data.babList || []);
setSubBabList(data.subBabList || []);
setMateriList(data.materiList || []);
} else {
showToast('Database MySQL kosong, menggunakan data demo KBC.', 'info');
loadOfflineData();
}
} catch (error) {
loadOfflineData();
} finally {
setLoading(false);
}
};
const loadOfflineData = () => {
setBabList([
{ id: 1, kelas_id: 1, nomor: 1, nama: "Bab 1: Aku Cinta Dua Kalimat Syahadat" },
{ id: 2, kelas_id: 1, nomor: 2, nama: "Bab 2: Mengenal Allah Melalui Ar-Rahman dan Ar-Rahim" },
{ id: 3, kelas_id: 1, nomor: 3, nama: "Bab 3: Adab Mandi dan Berpakaian Bersih" },
{ id: 4, kelas_id: 1, nomor: 4, nama: "Bab 4: Menghormati Orang Tua dan Guru" },
{ id: 5, kelas_id: 1, nomor: 5, nama: "Bab 5: Kisah Keteladanan Nabi Muhammad SAW" }
]);
setSubBabList([
{ id: 1, bab_id: 1, nomor: 1, nama: "Sub Bab 1: Tujuan Pembelajaran & Refleksi Mulia" },
{ id: 2, bab_id: 1, nomor: 2, nama: "Sub Bab 2: Kajian Materi & Dalil Al-Qur'an/Hadis" },
{ id: 3, bab_id: 1, nomor: 3, nama: "Sub Bab 3: Implementasi Kurikulum Berbasis Cinta (KBC)" },
{ id: 4, bab_id: 1, nomor: 4, nama: "Sub Bab 4: Kisah Inspiratif Pembawa Hikmah" },
{ id: 5, bab_id: 1, nomor: 5, nama: "Sub Bab 5: Rangkuman Intisari Pembelajaran" },
{ id: 6, bab_id: 1, nomor: 6, nama: "Sub Bab 6: Asesmen Sumatif & Evaluasi Mandiri" }
]);
setMateriList([
{
id: 1,
sub_bab_id: 1,
judul: "Mari Mengenal Dua Kalimat Syahadat",
konten: `
Assalamu'alaikum Warahmatullahi Wabarakatuh. Anak-anakku yang hebat, cerdas, dan shalih-shalihah, selamat datang di Kurikulum Berbasis Cinta (KBC)!
Pada bab pertama ini, kita akan bersama-sama menanamkan rasa cinta kita kepada Allah dan Rasul-Nya melalui pondasi utama keimanan kita, yaitu Dua Kalimat Syahadat (Syahadatain).
أَشْهَدُ أَنْ لَا إِلَهَ إِلَّا اللهُ وَأَشْهَدُ أَنَّ مُحَمَّا رَسُولُ اللهِ
"Aku bersaksi bahwa tiada Tuhan selain Allah, dan aku bersaksi bahwa Nabi Muhammad adalah utusan Allah."
`,
media: {
gambar: "https://images.unsplash.com/photo-1564507592333-c60657eea523?auto=format&fit=crop&w=800&q=80",
pdf_nama: "syahadatain_kurikulum_kbc_k1.pdf",
video_url: "https://www.w3schools.com/html/mov_bbb.mp4",
youtube_url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
},
penulis: "Ustadzah Aisyah Rahma, S.Pd",
diupdate_pada: "2026-06-28 08:30"
}
]);
};
const showToast = (message, type = 'success') => {
setToast({ show: true, message, type });
setTimeout(() => {
setToast({ show: false, message: '', type: 'success' });
}, 4000);
};
const addLog = (aksi, user = isLoggedIn ? 'Admin' : 'Tamu') => {
const waktu = new Date().toISOString().replace('T', ' ').substring(0, 16);
setAdminLogs(prev => [{ waktu, aksi, user }, ...prev]);
};
const filteredBab = useMemo(() => {
if (!selectedClass) return [];
return babList.filter(b => Number(b.kelas_id) === selectedClass.id);
}, [selectedClass, babList]);
const filteredSubBab = useMemo(() => {
if (!selectedBab) return [];
return subBabList.filter(sb => Number(sb.bab_id) === selectedBab.id);
}, [selectedBab, subBabList]);
const formSubBabList = useMemo(() => {
return subBabList.filter(sb => Number(sb.bab_id) === Number(materiForm.bab_id));
}, [materiForm.bab_id, subBabList]);
const formBabList = useMemo(() => {
return babList.filter(b => Number(b.kelas_id) === Number(materiForm.class_id));
}, [materiForm.class_id, babList]);
const searchResults = useMemo(() => {
if (!searchQuery.trim()) return [];
const query = searchQuery.toLowerCase();
return materiList.map(materi => {
const sub = subBabList.find(s => Number(s.id) === Number(materi.sub_bab_id));
const bab = sub ? babList.find(b => Number(b.id) === Number(sub.bab_id)) : null;
const klis = bab ? classes.find(c => Number(c.id) === Number(bab.kelas_id)) : null;
return {
materi, sub, bab, kelas: klis,
matchScore: (
(materi.judul.toLowerCase().includes(query) ? 3 : 0) +
(materi.konten.toLowerCase().includes(query) ? 1 : 0) +
(sub?.nama.toLowerCase().includes(query) ? 2 : 0) +
(bab?.nama.toLowerCase().includes(query) ? 2 : 0)
)
};
}).filter(res => res.matchScore > 0);
}, [searchQuery, materiList, subBabList, babList, classes]);
const handleLogin = async (e) => {
e.preventDefault();
try {
const response = await fetch(`${API_URL}?action=login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(loginForm)
});
const data = await response.json();
if (data.status === 'success') {
setIsLoggedIn(true);
setShowLoginModal(false);
setLoginForm({ username: '', password: '' });
setLoginError('');
showToast('Login berhasil sebagai Admin!', 'success');
addLog('Login admin berhasil terautentikasi.', data.user.nama_lengkap);
} else {
setLoginError(data.message);
}
} catch (err) {
if (loginForm.username === 'admin' && loginForm.password === 'akidahmi123') {
setIsLoggedIn(true);
setShowLoginModal(false);
setLoginForm({ username: '', password: '' });
showToast('Login berhasil (Mode Offline)!', 'success');
} else {
setLoginError('Koneksi database cPanel offline. Gunakan kredensial default.');
}
}
};
const handleLogout = () => {
setIsLoggedIn(false);
setCurrentView('home');
showToast('Logout berhasil.', 'info');
};
const navigateToMateri = (subBabId) => {
const foundSub = subBabList.find(sb => Number(sb.id) === Number(subBabId));
if (!foundSub) return;
const foundBab = babList.find(b => Number(b.id) === Number(foundSub.bab_id));
const foundClass = classes.find(c => Number(c.id) === Number(foundBab.kelas_id));
const foundMateri = materiList.find(m => Number(m.sub_bab_id) === Number(subBabId));
setSelectedClass(foundClass);
setSelectedBab(foundBab);
setSelectedSubBab(foundSub);
setSelectedMateri(foundMateri || null);
setCurrentView('materi-baca');
};
const handleDeleteMateri = async (id) => {
if (confirm('Apakah Anda yakin ingin menghapus materi ini dari database?')) {
try {
const response = await fetch(`${API_URL}?action=delete_materi&id=${id}`);
const data = await response.json();
if (data.status === 'success') {
showToast('Materi berhasil dihapus!', 'success');
loadDatabaseFromMySQL();
}
} catch (err) {
showToast('Koneksi server gagal.', 'error');
}
}
};
const handleSaveMateri = async (e) => {
e.preventDefault();
const payload = {
id: formMode === 'add' ? null : materiForm.id,
sub_bab_id: Number(materiForm.sub_bab_id),
judul: materiForm.judul,
konten: materiForm.konten,
penulis: materiForm.penulis || 'Guru Pengampu',
media: {
gambar: materiForm.gambar || '',
pdf_nama: materiForm.pdf_nama || '',
video_url: materiForm.video_url || '',
youtube_url: materiForm.youtube_url || ''
}
};
try {
const response = await fetch(`${API_URL}?action=save_materi`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
const data = await response.json();
if (data.status === 'success') {
showToast('Materi berhasil disimpan!', 'success');
await loadDatabaseFromMySQL();
navigateToMateri(materiForm.sub_bab_id);
}
} catch (err) {
showToast('Gagal terhubung ke database. Data tidak tersimpan.', 'error');
}
};
const handleSaveBab = async (e) => {
e.preventDefault();
if (!editingBabName.trim()) return;
const payload = {
id: editingBabId,
kelas_id: Number(selectedAdminClassId),
nomor: Number(editingBabNomor),
nama: `Bab ${editingBabNomor}: ${editingBabName.replace(/^Bab \d+:\s*/i, '')}`
};
try {
const response = await fetch(`${API_URL}?action=save_bab`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
const data = await response.json();
if (data.status === 'success') {
showToast('Bab berhasil disimpan!', 'success');
setEditingBabId(null);
setEditingBabName('');
loadDatabaseFromMySQL();
}
} catch (err) {
showToast('Gagal koneksi server.', 'error');
}
};
const handleDeleteBab = async (id) => {
if (confirm('Hapus Bab ini dari database?')) {
try {
await fetch(`${API_URL}?action=delete_bab&id=${id}`);
showToast('Bab berhasil dihapus!', 'success');
loadDatabaseFromMySQL();
} catch (err) {
showToast('Gagal menghapus.', 'error');
}
}
};
const handleSaveSubBab = async (e) => {
e.preventDefault();
if (!editingSubBabName.trim()) return;
const payload = {
id: editingSubBabId,
bab_id: Number(selectedAdminBabId),
nomor: Number(editingSubBabNomor),
nama: `Sub Bab ${editingSubBabNomor}: ${editingSubBabName.replace(/^Sub Bab \d+:\s*/i, '')}`
};
try {
const response = await fetch(`${API_URL}?action=save_sub_bab`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
const data = await response.json();
if (data.status === 'success') {
showToast('Sub-Bab berhasil disimpan!', 'success');
setEditingSubBabId(null);
setEditingSubBabName('');
loadDatabaseFromMySQL();
}
} catch (err) {
showToast('Gagal koneksi server.', 'error');
}
};
const handleDeleteSubBab = async (id) => {
if (confirm('Hapus Sub-Bab ini?')) {
try {
await fetch(`${API_URL}?action=delete_sub_bab&id=${id}`);
showToast('Sub-Bab berhasil dihapus!', 'success');
loadDatabaseFromMySQL();
} catch (err) {
showToast('Gagal menghapus.', 'error');
}
}
};
const openMateriForm = (mode, targetMateri = null) => {
if (mode === 'add') {
setFormMode('add');
setMateriForm({
id: null, class_id: selectedClass ? selectedClass.id : 1,
bab_id: selectedBab ? selectedBab.id : 1,
sub_bab_id: selectedSubBab ? selectedSubBab.id : 1,
judul: '', konten: '', gambar: '', pdf_nama: '',
video_url: '', youtube_url: '', penulis: 'Pendidik KBC'
});
} else {
setFormMode('edit');
setMateriForm({
id: targetMateri.id,
class_id: selectedClass ? selectedClass.id : 1,
bab_id: selectedBab ? selectedBab.id : 1,
sub_bab_id: targetMateri.sub_bab_id,
judul: targetMateri.judul,
konten: targetMateri.konten,
gambar: targetMateri.media?.gambar || '',
pdf_nama: targetMateri.media?.pdf_nama || '',
video_url: targetMateri.media?.video_url || '',
youtube_url: targetMateri.media?.youtube_url || '',
penulis: targetMateri.penulis
});
}
setIsPreviewFormMode(false);
setCurrentView('admin-materi-form');
};
const handleBackup = () => {
const databaseJSON = JSON.stringify({ classes, babList, subBabList, materiList }, null, 2);
const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(databaseJSON);
const linkElement = document.createElement('a');
linkElement.setAttribute('href', dataUri);
linkElement.setAttribute('download', 'backup_akidah_kbc_mi.json');
linkElement.click();
showToast('Backup JSON berhasil diunduh!', 'success');
};
const handleImport = (e) => {
const fileReader = new FileReader();
if (e.target.files.length > 0) {
fileReader.readAsText(e.target.files[0], "UTF-8");
fileReader.onload = (event) => {
try {
const parsed = JSON.parse(event.target.result);
if (parsed.materiList && parsed.babList && parsed.subBabList) {
setBabList(parsed.babList);
setSubBabList(parsed.subBabList);
setMateriList(parsed.materiList);
showToast('Data materi Kurikulum KBC sukses di-import!', 'success');
}
} catch (err) {
showToast('Gagal memproses berkas JSON.', 'error');
}
};
}
};
return (
{/* ==========================================
HEADER NAVBAR (PREMIUM STYLE)
========================================== */}
setIsSidebarOpen(!isSidebarOpen)} className="p-2 rounded-xl text-emerald-800 dark:text-emerald-400 hover:bg-emerald-50 dark:hover:bg-slate-900 transition-all">
{ setCurrentView('home'); setSelectedClass(null); }}>
🕌
Akidah Akhlak MI
Kurikulum Berbasis Cinta (KBC)
setTheme(theme === 'light' ? 'dark' : 'light')} className="p-2.5 rounded-full hover:bg-slate-100 dark:hover:bg-slate-900 transition-colors">
{theme === 'light' ? : }
{isLoggedIn && (
setCurrentView('admin-dashboard')} className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-bold bg-amber-100 text-amber-800 dark:bg-amber-950/50 dark:text-amber-300">
Dashboard
)}
{isLoggedIn ? (
Keluar
) : (
setShowLoginModal(true)} className="bg-emerald-600 hover:bg-emerald-700 text-white font-bold text-xs px-4 py-2 rounded-xl transition-all shadow-md">Masuk Guru
)}
{/* Loading State Overlay */}
{loading && (
Mengkoneksikan & memuat data dari database MySQL cPanel...
)}
{/* ==========================================
SIDEBAR NAVIGATION (PREMIUM DESIGN)
========================================== */}
{isSidebarOpen && (
STRUKTUR KELAS & ATP
IKM Kemenag
{classes.map((kls) => {
const isSelected = selectedClass?.id === kls.id;
return (
{ setSelectedClass(kls); setSelectedBab(null); setCurrentView('kelas-detail'); }}
className={`w-full text-left p-3 rounded-xl transition-all text-xs font-bold flex items-center justify-between border ${
isSelected
? 'bg-gradient-to-r from-emerald-800 to-emerald-700 text-white border-transparent shadow-lg shadow-emerald-900/10'
: 'hover:bg-slate-50 dark:hover:bg-slate-900 text-slate-700 dark:text-slate-300 border-transparent'
}`}
>
{kls.id}
{kls.nama}
{/* Nested Bab and Sub-Bab under selected Class in Sidebar */}
{isSelected && (
{babList.filter(b => Number(b.kelas_id) === kls.id).length === 0 ? (
Belum ada Bab pembelajaran
) : (
babList.filter(b => Number(b.kelas_id) === kls.id).map(bab => (
{bab.nama}
{subBabList.filter(s => Number(s.bab_id) === bab.id).map(sub => (
{
setSelectedBab(bab);
setSelectedSubBab(sub);
setSelectedMateri(materiList.find(m => Number(m.sub_bab_id) === sub.id) || null);
setCurrentView('materi-baca');
}}
className={`w-full text-left text-[11px] py-1 px-2 rounded-lg transition-colors block truncate ${
selectedSubBab?.id === sub.id
? 'bg-emerald-50 dark:bg-emerald-950/40 text-emerald-700 dark:text-emerald-400 font-bold border-l-2 border-emerald-600 pl-3'
: 'text-slate-500 hover:text-emerald-700 dark:hover:text-emerald-400 pl-3'
}`}
>
{sub.nama.split(': ')[0]}
))}
))
)}
)}
);
})}
)}
{/* ==========================================
MAIN CONTENT WINDOW
========================================== */}
{currentView === 'home' && (
🕌
Kurikulum Berbasis Cinta (KBC)
Portal Belajar Akidah Akhlak
Membangun akhlak mulia dan akidah Islamiah berbasis kecintaan tulus kepada Allah SWT, sesama manusia, dan alam semesta.
{/* INTEGRASI KBC HIGHLIGHT */}
⭐
Fokus Utama: Kurikulum Berbasis Cinta (KBC)
Kurikulum di Madrasah Ibtidaiyah menekankan pembelajaran bermakna berlandaskan cinta kasih untuk menghasilkan generasi muslim yang tulus, berakhlak mulia melalui pendekatan Kurikulum Berbasis Cinta (KBC), toleran, beradab, serta memiliki empati tinggi. Setiap sub-bab dilengkapi aksi nyata berbasis empati dan cinta kasih yang kontekstual.
)}
{currentView === 'kelas-detail' && selectedClass && (
Alur Pembelajaran {selectedClass.nama}
{isLoggedIn && (
{ setAdminActiveTab('bab'); setCurrentView('admin-dashboard'); }} className="text-xs bg-emerald-600 hover:bg-emerald-700 text-white px-3.5 py-2 rounded-xl font-bold flex items-center gap-1.5 font-sans">
Kelola Bab / Sub-Bab
)}
{babList.filter(b => Number(b.kelas_id) === selectedClass.id).map((bab) => (
{`Bab ${bab.nomor}`}
{bab.nama}
{subBabList.filter(s => Number(s.bab_id) === bab.id).map(sub => (
{
setSelectedBab(bab);
setSelectedSubBab(sub);
setSelectedMateri(materiList.find(m => Number(m.sub_bab_id) === sub.id) || null);
setCurrentView('materi-baca');
}}
className="w-full text-left text-xs text-slate-650 dark:text-slate-400 hover:text-emerald-600 font-medium py-1 flex items-center justify-between font-sans"
>
{sub.nama}
))}
))}
)}
{currentView === 'materi-baca' && selectedSubBab && (
{selectedClass?.nama} ➔ {selectedBab?.nama.split(': ')[0]}
{selectedSubBab.nama}
{isLoggedIn && (
openMateriForm('edit', selectedMateri)} className="p-2 text-amber-600 hover:bg-amber-50 rounded-xl">
{selectedMateri && (
handleDeleteMateri(selectedMateri.id)} className="p-2 text-rose-600 hover:bg-rose-50 rounded-xl">
)}
)}
{selectedMateri ? (
Ditulis oleh: {selectedMateri.penulis} | Terakhir diupdate: {selectedMateri.diupdate_pada}
{selectedMateri.media?.gambar && (
)}
{/* Lampiran Media */}
{(selectedMateri.media?.pdf_nama || selectedMateri.media?.youtube_url) && (
📚 Sumber Belajar Tambahan
{selectedMateri.media.pdf_nama && (
{selectedMateri.media.pdf_nama}
showToast('Mengunduh berkas PDF...')} className="text-emerald-600 hover:underline text-xs font-bold">Unduh PDF
)}
{selectedMateri.media.youtube_url && (
)}
)}
) : (
Materi belum diisi oleh guru pengampu.
{isLoggedIn && (
openMateriForm('add')} className="bg-emerald-600 hover:bg-emerald-700 text-white font-bold text-xs px-4 py-2 rounded-xl transition-all font-sans">Isi Materi
)}
)}
)}
{/* ========================================================
VIEW 5: ADMIN DASHBOARD (DENGAN TIGA TAB KELOLA)
======================================================== */}
{currentView === 'admin-dashboard' && isLoggedIn && (
{/* Tabs */}
setAdminActiveTab('materi')} className={`py-2 px-4 text-xs font-bold ${adminActiveTab === 'materi' ? 'border-b-2 border-emerald-600 text-emerald-600' : 'text-slate-400'}`}>Kelola Materi
setAdminActiveTab('bab')} className={`py-2 px-4 text-xs font-bold ${adminActiveTab === 'bab' ? 'border-b-2 border-emerald-600 text-emerald-600' : 'text-slate-400'}`}>Kelola Struktur Bab
setAdminActiveTab('sub_bab')} className={`py-2 px-4 text-xs font-bold ${adminActiveTab === 'sub_bab' ? 'border-b-2 border-emerald-600 text-emerald-600' : 'text-slate-400'}`}>Kelola Struktur Sub-Bab
{/* TAB CONTENT: KELOLA MATERI */}
{adminActiveTab === 'materi' && (
Daftar Modul Terbit
openMateriForm('add')} className="bg-emerald-600 hover:bg-emerald-700 text-white text-xs font-bold px-3 py-1.5 rounded-lg flex items-center gap-1 font-sans font-sans"> Tambah Materi
{materiList.map(m => (
{m.judul}
Penulis: {m.penulis}
navigateToMateri(m.sub_bab_id)} className="text-emerald-600 font-semibold hover:underline">Lihat
openMateriForm('edit', m)} className="text-amber-600 font-semibold hover:underline">Ubah
handleDeleteMateri(m.id)} className="text-rose-600 font-semibold hover:underline">Hapus
))}
)}
{/* TAB CONTENT: KELOLA BAB */}
{adminActiveTab === 'bab' && (
{editingBabId ? 'Ubah Bab' : 'Tambah Bab'}
Daftar Bab Kelas Terpilih
{babList.filter(b => Number(b.kelas_id) === Number(selectedAdminClassId)).map(b => (
{b.nama}
{ setEditingBabId(b.id); setEditingBabNomor(b.nomor); setEditingBabName(b.nama); }} className="text-amber-500 hover:underline">Edit
handleDeleteBab(b.id)} className="text-rose-500 hover:underline font-sans font-sans">Hapus
))}
)}
{/* TAB CONTENT: KELOLA SUB-BAB */}
{adminActiveTab === 'sub_bab' && (
{editingSubBabId ? 'Ubah Sub-Bab' : 'Tambah Sub-Bab'}
Daftar Sub-Bab
{subBabList.filter(s => Number(s.bab_id) === Number(selectedAdminBabId)).map(s => (
{s.nama}
{ setEditingSubBabId(s.id); setEditingSubBabNomor(s.nomor); setEditingSubBabName(s.nama); }} className="text-amber-500 hover:underline">Edit
handleDeleteSubBab(s.id)} className="text-rose-500 hover:underline">Hapus
))}
)}
)}
{/* ========================================================
VIEW 6: EDITOR FORM (TAMBAH & EDIT MATERI)
======================================================== */}
{currentView === 'admin-materi-form' && isLoggedIn && (
{formMode === 'add' ? 'Tambah Modul Materi Baru' : 'Ubah Modul Materi'}
setCurrentView('admin-dashboard')} className="text-xs text-rose-500 font-bold bg-rose-50 px-3 py-1.5 rounded-lg">Kembali
)}
{/* ==========================================
MODAL LOGIN GURU / ADMIN
========================================== */}
{showLoginModal && (
{ setShowLoginModal(false); setLoginError(''); }}
className="absolute right-4 top-4 p-1.5 rounded-full hover:bg-slate-100 dark:hover:bg-slate-800 text-slate-400 hover:text-slate-655 transition-colors"
>
🕌
Login Pendidik (Guru)
Kurikulum KBC MI
{loginError && (
{loginError}
)}
Username Admin *
setLoginForm(prev => ({ ...prev, username: e.target.value }))}
className="w-full bg-slate-50 dark:bg-slate-950 border border-slate-200 dark:border-slate-800 rounded-xl p-2.5 text-xs focus:ring-1 focus:ring-emerald-500 focus:outline-none bg-transparent"
required
/>
Password *
setLoginForm(prev => ({ ...prev, password: e.target.value }))}
className="w-full bg-slate-50 dark:bg-slate-950 border border-slate-200 dark:border-slate-800 rounded-xl p-2.5 text-xs focus:ring-1 focus:ring-emerald-500 focus:outline-none bg-transparent"
required
/>
Masuk Ke Dashboard
)}
{/* FOOTER */}
);
}
// Inisialisasi render ReactDOM murni di akhir berkas
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( );