import React, { useState, useEffect } from 'react'; import { School, ShieldCheck, UploadCloud, Image as ImageIcon, CheckCircle2, AlertCircle, LogOut, User, ExternalLink, Plus, Trash2, Eye, EyeOff, X, Bell, Calendar, Database, ArrowUpRight, Sparkles, Lock, ChevronRight, Activity, Server, Users, FileText, MessageSquare, Send, Clock, Laptop, Search, Edit3, GraduationCap, RotateCcw, Key, Copy, Check, Palette, Settings, RefreshCw, Globe, Sliders, Paintbrush } from 'lucide-react'; interface GTKRecord { id: number; nama: string; nuptk: string; npk: string; nik: string; passwordEmisGtk: string; jabatan: string; mapel: string; statusPegawai: string; sertifikasi: string; statusSimpatika: string; jtm: number; pendidikan: string; tmt: string; noHp: string; } interface PhotoRecord { id: number; title: string; category: string; date: string; url: string; caption: string; } interface AnnouncementRecord { id: number; title: string; date: string; category: string; urgent: boolean; text: string; } type ThemeKey = 'emerald' | 'indigo' | 'amber' | 'blue' | 'rose'; interface ThemeConfig { name: string; primary: string; accentBg: string; accentText: string; accentBorder: string; accentBadge: string; gradientBtn: string; glowBg: string; glowHero: string; activeTab: string; previewColor: string; } const themeMap: Record = { emerald: { name: 'Emerald Green (Klasik)', primary: 'emerald', accentBg: 'bg-emerald-500 hover:bg-emerald-400', accentText: 'text-emerald-400', accentBorder: 'border-emerald-500/30', accentBadge: 'bg-emerald-950 text-emerald-400 border-emerald-500/40', gradientBtn: 'from-emerald-400 to-teal-500 hover:from-emerald-300 hover:to-teal-400', glowBg: 'bg-emerald-600/15', glowHero: 'bg-emerald-500/10', activeTab: 'bg-emerald-500 text-slate-950 shadow-emerald-500/20', previewColor: 'bg-emerald-500' }, indigo: { name: 'Indigo Cyber', primary: 'indigo', accentBg: 'bg-indigo-500 hover:bg-indigo-400', accentText: 'text-indigo-400', accentBorder: 'border-indigo-500/30', accentBadge: 'bg-indigo-950 text-indigo-400 border-indigo-500/40', gradientBtn: 'from-indigo-400 to-purple-500 hover:from-indigo-300 hover:to-purple-400', glowBg: 'bg-indigo-600/15', glowHero: 'bg-indigo-500/10', activeTab: 'bg-indigo-500 text-slate-950 shadow-indigo-500/20', previewColor: 'bg-indigo-500' }, amber: { name: 'Islamic Gold Amber', primary: 'amber', accentBg: 'bg-amber-500 hover:bg-amber-400', accentText: 'text-amber-400', accentBorder: 'border-amber-500/30', accentBadge: 'bg-amber-950 text-amber-400 border-amber-500/40', gradientBtn: 'from-amber-400 to-yellow-500 hover:from-amber-300 hover:to-yellow-400', glowBg: 'bg-amber-600/15', glowHero: 'bg-amber-500/10', activeTab: 'bg-amber-500 text-slate-950 shadow-amber-500/20', previewColor: 'bg-amber-500' }, blue: { name: 'Ocean Azure Blue', primary: 'sky', accentBg: 'bg-sky-500 hover:bg-sky-400', accentText: 'text-sky-400', accentBorder: 'border-sky-500/30', accentBadge: 'bg-sky-950 text-sky-400 border-sky-500/40', gradientBtn: 'from-sky-400 to-blue-500 hover:from-sky-300 hover:to-blue-400', glowBg: 'bg-sky-600/15', glowHero: 'bg-sky-500/10', activeTab: 'bg-sky-500 text-slate-950 shadow-sky-500/20', previewColor: 'bg-sky-500' }, rose: { name: 'Crimson Rose Premium', primary: 'rose', accentBg: 'bg-rose-500 hover:bg-rose-400', accentText: 'text-rose-400', accentBorder: 'border-rose-500/30', accentBadge: 'bg-rose-950 text-rose-400 border-rose-500/40', gradientBtn: 'from-rose-400 to-pink-500 hover:from-rose-300 hover:to-pink-400', glowBg: 'bg-rose-600/15', glowHero: 'bg-rose-500/10', activeTab: 'bg-rose-500 text-slate-950 shadow-rose-500/20', previewColor: 'bg-rose-500' } }; export default function App() { // State Autentikasi & Tampilan const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false); const [currentView, setCurrentView] = useState<'public' | 'admin' | 'login'>('public'); const [adminTab, setAdminTab] = useState<'database-gtk' | 'upload-foto' | 'pengumuman' | 'update-website'>('database-gtk'); const [loginEmail, setLoginEmail] = useState('alwikahfi'); const [loginPassword, setLoginPassword] = useState('operator123'); const [loginError, setLoginError] = useState(''); // Config Website Kustom & Tema Dinamis const [activeTheme, setActiveTheme] = useState('emerald'); const [siteConfig, setSiteConfig] = useState({ schoolName: 'MA MAMBAUL HIKMAH', subTitle: 'Sistem Informasi Data Pokok Madrasah & Ekosistem IT', heroTitle: 'Integrasi Layanan Data & Ekosistem Digital Madrasah', heroSubtitle: 'Portal resmi pengelolaan data Guru & Tenaga Kependidikan (GTK), akses server Rapor Digital Madrasah (RDM), serta pengaduan verval data peserta didik secara langsung.', runningAnnouncement: 'Selamat datang di Portal Operator MA Mambaul Hikmah. Layanan data terpadu EMIS 4.0, SIMPATIKA, & RDM Aktif.', whatsappNumber: '6281234567890', lastUpdated: '03 Sep 2026, 08:30 WIB' }); // State Form Update Website di Admin Panel const [tempConfig, setTempConfig] = useState({ ...siteConfig }); const [tempTheme, setTempTheme] = useState('emerald'); const [isUpdatingSite, setIsUpdatingSite] = useState(false); // Dynamic style object helper const theme = themeMap[activeTheme]; // Jam Operasional Digital const [timeString, setTimeString] = useState(''); useEffect(() => { const updateTimer = () => { const now = new Date(); setTimeString( now.toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }) + ' WIB' ); }; updateTimer(); const interval = setInterval(updateTimer, 1000); return () => clearInterval(interval); }, []); useEffect(() => { try { const path = window.location.pathname || ''; const hash = window.location.hash || ''; if (path.endsWith('/login') || hash === '#/login' || hash === '#login') { setCurrentView('login'); } } catch { // Safe fallback } const handlePopState = () => { try { const path = window.location.pathname || ''; const hash = window.location.hash || ''; if (path.endsWith('/login') || hash === '#/login' || hash === '#login') { setCurrentView('login'); } else if (!isAdminLoggedIn) { setCurrentView('public'); } } catch { // Safe fallback } }; window.addEventListener('popstate', handlePopState); return () => window.removeEventListener('popstate', handlePopState); }, [isAdminLoggedIn]); // State Notifikasi Toast const [toast, setToast] = useState<{ show: boolean; message: string; type: 'success' | 'error' | 'info' }>({ show: false, message: '', type: 'success' }); const showToast = (message: string, type: 'success' | 'error' | 'info' = 'success') => { setToast({ show: true, message, type }); setTimeout(() => { setToast({ show: false, message: '', type: 'success' }); }, 3500); }; // State Visibilitas Password EMIS GTK di Admin Table const [visiblePasswords, setVisiblePasswords] = useState<{ [id: number]: boolean }>({}); const [copiedId, setCopiedId] = useState(null); const togglePasswordVisibility = (id: number) => { setVisiblePasswords((prev) => ({ ...prev, [id]: !prev[id] })); }; const copyToClipboard = (text: string, id: number, label: string) => { navigator.clipboard.writeText(text); setCopiedId(id); showToast(`${label} berhasil disalin!`, 'info'); setTimeout(() => setCopiedId(null), 2000); }; // Master Data GTK const [gtkList, setGtkList] = useState([ { id: 1, nama: 'Drs. H. Ahmad Fauzi, M.Pd.I', nuptk: '4538749651200032', npk: '849201948201', nik: '3509121508750001', passwordEmisGtk: 'FauziEmis2026!', jabatan: 'Kepala Madrasah / Guru Fiqih', mapel: 'Fiqih & Ushul Fiqih', statusPegawai: 'PNS Kemenag', sertifikasi: 'Sudah Sertifikasi', statusSimpatika: 'Aktif (S25a Valid)', jtm: 24, pendidikan: 'S2 Magister Pendidikan Islam', tmt: '01 Juli 2008', noHp: '081234567801' }, { id: 2, nama: 'Siti Nurhaliza, S.Pd.', nuptk: '8342751653300021', npk: '729103859201', nik: '3509125406880002', passwordEmisGtk: 'Nurhaliza99#', jabatan: 'Guru Matematika', mapel: 'Matematika Peminatan & Wajib', statusPegawai: 'PPPK', sertifikasi: 'Sudah Sertifikasi', statusSimpatika: 'Aktif (S25a Valid)', jtm: 28, pendidikan: 'S1 Pendidikan Matematika', tmt: '10 Januari 2015', noHp: '081234567802' }, { id: 3, nama: 'Muhammad Hasan Basri, S.Kom.', nuptk: '1947762664130043', npk: '619204859102', nik: '3509122311920004', passwordEmisGtk: 'HasanB2026*', jabatan: 'Guru Informatika & Teknisi Lab', mapel: 'Informatika & Komputer', statusPegawai: 'Non-ASN / GTT', sertifikasi: 'Belum Sertifikasi', statusSimpatika: 'Aktif (Ajuan S25)', jtm: 24, pendidikan: 'S1 Teknik Informatika', tmt: '15 Juli 2019', noHp: '081234567803' }, { id: 4, nama: 'Nurul Hidayah, S.Pd.I.', nuptk: '6245758660300012', npk: '539102849201', nik: '3509124903910003', passwordEmisGtk: 'NurulArab2026', jabatan: 'Guru Bahasa Arab', mapel: 'Bahasa Arab & Hadits', statusPegawai: 'Non-ASN / GTT', sertifikasi: 'Sudah Sertifikasi', statusSimpatika: 'Aktif (S25a Valid)', jtm: 26, pendidikan: 'S1 Pendidikan Bahasa Arab', tmt: '01 Agustus 2017', noHp: '081234567804' }, { id: 5, nama: 'Bambang Triyono, S.E.', nuptk: '-', npk: '429103849103', nik: '3509121804860005', passwordEmisGtk: 'BambangTU2026!', jabatan: 'Kepala Tata Usaha & Kepegawaian', mapel: 'Administrasi Madrasah', statusPegawai: 'Non-ASN / PTT', sertifikasi: 'Bukan Guru', statusSimpatika: 'Aktif (Tendik)', jtm: 0, pendidikan: 'S1 Ekonomi Akuntansi', tmt: '02 Mei 2012', noHp: '081234567805' } ]); // Public Search State const [publicGtkInput, setPublicGtkInput] = useState(''); const [publicGtkFilter, setPublicGtkFilter] = useState('Semua'); const [hasSearched, setHasSearched] = useState(false); const [publicSearchResults, setPublicSearchResults] = useState([]); const [selectedGtkModal, setSelectedGtkModal] = useState(null); const handleExecuteSearchGtk = (e?: React.FormEvent) => { if (e) e.preventDefault(); const query = publicGtkInput.trim().toLowerCase(); if (!query) { showToast('Masukkan nama, NUPTK, NPK, atau mapel yang dicari!', 'info'); return; } const results = gtkList.filter((gtk) => { const matchQuery = gtk.nama.toLowerCase().includes(query) || gtk.nuptk.includes(query) || gtk.npk.includes(query) || gtk.mapel.toLowerCase().includes(query) || gtk.jabatan.toLowerCase().includes(query); if (publicGtkFilter === 'Semua') return matchQuery; if (publicGtkFilter === 'Sertifikasi') return matchQuery && gtk.sertifikasi === 'Sudah Sertifikasi'; if (publicGtkFilter === 'PNS/PPPK') return matchQuery && (gtk.statusPegawai.includes('PNS') || gtk.statusPegawai.includes('PPPK')); if (publicGtkFilter === 'GTT') return matchQuery && gtk.statusPegawai.includes('GTT'); return matchQuery; }); setPublicSearchResults(results); setHasSearched(true); showToast(`Ditemukan ${results.length} data pendidik.`, 'success'); }; const handleResetSearchGtk = () => { setPublicGtkInput(''); setHasSearched(false); setPublicSearchResults([]); showToast('Form pencarian telah direset.', 'info'); }; // Admin GTK CRUD State const [adminGtkSearch, setAdminGtkSearch] = useState(''); const [showGtkFormModal, setShowGtkFormModal] = useState(false); const [isEditingGtk, setIsEditingGtk] = useState(false); const [currentGtkForm, setCurrentGtkForm] = useState({ id: 0, nama: '', nuptk: '', npk: '', nik: '', passwordEmisGtk: '', jabatan: '', mapel: '', statusPegawai: 'PNS Kemenag', sertifikasi: 'Sudah Sertifikasi', statusSimpatika: 'Aktif (S25a Valid)', jtm: 24, pendidikan: 'S1', tmt: '', noHp: '' }); const handleOpenAddGtk = () => { setIsEditingGtk(false); setCurrentGtkForm({ id: 0, nama: '', nuptk: '', npk: '', nik: '', passwordEmisGtk: 'Madrasah2026!', jabatan: 'Guru Mata Pelajaran', mapel: '', statusPegawai: 'Non-ASN / GTT', sertifikasi: 'Belum Sertifikasi', statusSimpatika: 'Aktif (S25a Valid)', jtm: 24, pendidikan: 'S1 Pendidikan', tmt: new Date().toLocaleDateString('id-ID', { day: '2-digit', month: 'long', year: 'numeric' }), noHp: '' }); setShowGtkFormModal(true); }; const handleOpenEditGtk = (gtk: GTKRecord) => { setIsEditingGtk(true); setCurrentGtkForm({ ...gtk }); setShowGtkFormModal(true); }; const handleSaveGtk = (e: React.FormEvent) => { e.preventDefault(); if (!currentGtkForm.nama.trim()) { showToast('Nama guru / tendik wajib diisi!', 'error'); return; } if (isEditingGtk) { setGtkList(gtkList.map((g) => (g.id === currentGtkForm.id ? { ...currentGtkForm } : g))); showToast(`Data GTK "${currentGtkForm.nama}" berhasil diperbarui!`, 'success'); } else { const newEntry: GTKRecord = { ...currentGtkForm, id: Date.now() }; setGtkList([newEntry, ...gtkList]); showToast(`GTK baru "${newEntry.nama}" berhasil ditambahkan!`, 'success'); } setShowGtkFormModal(false); }; const handleDeleteGtk = (id: number, nama: string) => { setGtkList(gtkList.filter((g) => g.id !== id)); showToast(`Data GTK ${nama} telah dihapus dari sistem.`, 'info'); }; // State Form Verval PD const [vervalForm, setVervalForm] = useState({ namaSiswa: '', nisn: '', nik: '', kelas: 'X - 1 (Fase E)', kategori: 'Perbaikan Ejaan Nama Siswa', dataLama: '', dataBaru: '', dokumen: 'Akta Kelahiran & Kartu Keluarga', catatan: '' }); const handleVervalSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!vervalForm.namaSiswa || !vervalForm.nisn || !vervalForm.nik || !vervalForm.dataLama || !vervalForm.dataBaru) { showToast('Mohon lengkapi seluruh kolom formulir bertanda wajib!', 'error'); return; } const message = `*PENGADUAN PERBAIKAN DATA SISWA (VERVAL PD)* *${siteConfig.schoolName}* ==================================== • *Nama Siswa:* ${vervalForm.namaSiswa} • *NISN:* ${vervalForm.nisn} • *NIK Siswa:* ${vervalForm.nik} • *Kelas:* ${vervalForm.kelas} ------------------------------------ • *Jenis Perubahan:* ${vervalForm.kategori} • *Data Lama (Keliru):* ${vervalForm.dataLama} • *Data Baru (Valid):* ${vervalForm.dataBaru} • *Dokumen Bukti:* ${vervalForm.dokumen} • *Catatan Tambahan:* ${vervalForm.catatan || '-'} ==================================== _Diajukan melalui Portal Resmi Operator Madrasah._ _Foto bukti berkas (Akta/KK/Ijazah) segera saya lampirkan di chat ini._`; const encodedMessage = encodeURIComponent(message); const waUrl = `https://api.whatsapp.com/send?phone=${siteConfig.whatsappNumber}&text=${encodedMessage}`; window.open(waUrl, '_blank'); showToast('Mengarahkan ke WhatsApp Operator...', 'success'); }; // Ekosistem Layanan IT const services = [ { id: 'rdm', name: 'Rapor Digital Madrasah (RDM)', tag: 'Server Mandiri MA', status: 'Online', ping: '24ms', url: 'https://rdmma.mtsmambaulhikmah.sch.id/', desc: 'Pengolahan nilai akademik kurikulum merdeka, cetak leger, dan buku rapor siswa terpusat.', featured: true, icon: }, { id: 'emis', name: 'EMIS 4.0 Kemenag', tag: 'Pusat Data Pokok', status: 'Aktif', ping: '42ms', url: 'https://emis.kemenag.go.id', desc: 'Master database kelembagaan, registrasi siswa aktif, rombel, dan sarana prasarana nasional.', featured: false, icon: }, { id: 'emis-gtk', name: 'EMIS GTK', tag: 'Administrasi PTK', status: 'Online', ping: '38ms', url: 'https://emisgtk.kemenag.go.id/', desc: 'Sertifikasi guru, ajuan S25a, S29, keaktifan NPK/NUPTK, dan pencairan tunjangan profesi.', featured: false, icon: }, { id: 'vervalpd', name: 'Verval Peserta Didik', tag: 'Pusdatin Kemdikbud', status: 'Tersinkron', ping: '31ms', url: 'https://vervalpd.data.kemendikdasmen.go.id/index.php/Csekolah', desc: 'Validasi NIK kependudukan Dukcapil, verifikasi NISN ganda, dan penerbitan nomor ijazah.', featured: false, icon: }, { id: 'pdum', name: 'PDUM (Pangkalan Data Ujian)', tag: 'Asesmen Madrasah', status: 'Siap', ping: '29ms', url: 'https://pdum.kemenag.go.id/', desc: 'Pengelolaan data peserta Asesmen Madrasah, pencetakan DNT, kartu peserta, dan nomor ujian.', featured: false, icon: }, { id: 'nisn', name: 'Cek NISN', tag: 'Nomor Induk Siswa Nasional', status: 'Online', ping: '48ms', url: 'https://nisn.data.kemendikdasmen.go.id/', desc: 'Monitoring nomor induk siswa nasional dan status keaktifan peserta didik.', featured: false, icon: } ]; // Gallery State const [gallery, setGallery] = useState([ { id: 1, title: 'Sinkronisasi Server RDM Semester Genap', category: 'Infrastruktur Data', date: '02 Sep 2026', url: 'https://images.unsplash.com/photo-1558494949-ef010cbdcc31?q=80&w=900&auto=format&fit=crop', caption: 'Maintenance berkala dan backup database Rapor Digital Madrasah di ruang server operator.' }, { id: 2, title: 'Pelaksanaan Gladi Bersih Asesmen Madrasah Berbasis Komputer', category: 'Evaluasi Akademik', date: '20 Agu 2026', url: 'https://images.unsplash.com/photo-1516321318423-f06f85e504b3?q=80&w=900&auto=format&fit=crop', caption: 'Monitoring client CBT dan kesiapan jaringan gigabit LAN di Laboratorium Komputer 1.' }, { id: 3, title: 'Pemberkasan Dokumen S25a & Verifikasi SIMPATIKA GTK', category: 'Administrasi GTK', date: '15 Jul 2026', url: 'https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?q=80&w=900&auto=format&fit=crop', caption: 'Validasi jadwal mengajar 24 jam tatap muka mingguan dewan guru untuk ajuan SKBK.' } ]); const [newPhotoTitle, setNewPhotoTitle] = useState(''); const [newPhotoCategory, setNewPhotoCategory] = useState('Infrastruktur Data'); const [newPhotoCaption, setNewPhotoCaption] = useState(''); const [newPhotoPreview, setNewPhotoPreview] = useState(null); const [isUploading, setIsUploading] = useState(false); // Announcements State const [announcements, setAnnouncements] = useState([ { id: 1, title: 'Akses Portal RDM Telah Diarahkan ke Subdomain Mandiri', date: '01 Sep 2026', category: 'Sistem RDM', urgent: true, text: 'Kepada Yth. Bapak/Ibu Dewan Guru, portal RDM kini aktif di https://rdmma.mtsmambaulhikmah.sch.id/. Nilai asesmen kurikulum merdeka dapat diinput secara bertahap.' }, { id: 2, title: 'Pembersihan Residu NISN Siswa Kelas XII Menjelang Kelulusan', date: '28 Agu 2026', category: 'Verval PD', urgent: true, text: 'Bagi siswa yang nama atau tempat tanggal lahir di ijazah SMP berbeda dengan KK/Akta, segera isi formulir pengaduan perbaikan data di bawah untuk diproses ke Pusdatin.' }, { id: 3, title: 'Cetak Surat Pengantar Aktivasi Rekening SimPel PIP Tahap 2', date: '20 Agu 2026', category: 'Kesiswaan', urgent: false, text: 'Daftar penerima SK Nominasi PIP telah ditempel di papan pengumuman. Surat rekomendasi madrasah untuk bank penyalur dapat diambil di meja operator.' } ]); const [newAnnTitle, setNewAnnTitle] = useState(''); const [newAnnCategory, setNewAnnCategory] = useState('Sistem RDM'); const [newAnnText, setNewAnnText] = useState(''); const [newAnnUrgent, setNewAnnUrgent] = useState(false); const [previewModalPhoto, setPreviewModalPhoto] = useState(null); const handleFileChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; if (!file.type.startsWith('image/')) { showToast('Harap pilih berkas gambar yang sah (JPG/PNG)', 'error'); return; } const reader = new FileReader(); reader.onload = (event) => setNewPhotoPreview(event.target?.result as string); reader.readAsDataURL(file); }; const handleSavePhoto = (e: React.FormEvent) => { e.preventDefault(); if (!newPhotoTitle.trim() || !newPhotoPreview) { showToast('Lengkapi judul dan berkas foto!', 'error'); return; } setIsUploading(true); setTimeout(() => { setGallery([ { id: Date.now(), title: newPhotoTitle, category: newPhotoCategory, date: new Date().toLocaleDateString('id-ID', { day: '2-digit', month: 'short', year: 'numeric' }), url: newPhotoPreview, caption: newPhotoCaption || 'Dokumentasi kegiatan resmi madrasah.' }, ...gallery ]); setNewPhotoTitle(''); setNewPhotoCaption(''); setNewPhotoPreview(null); setIsUploading(false); showToast('Aset foto berhasil dipublikasikan ke galeri!', 'success'); }, 700); }; const handleAddAnnouncement = (e: React.FormEvent) => { e.preventDefault(); if (!newAnnTitle.trim() || !newAnnText.trim()) return; setAnnouncements([ { id: Date.now(), title: newAnnTitle, date: new Date().toLocaleDateString('id-ID', { day: '2-digit', month: 'short' }), category: newAnnCategory, urgent: newAnnUrgent, text: newAnnText }, ...announcements ]); setNewAnnTitle(''); setNewAnnText(''); setNewAnnUrgent(false); showToast('Edaran resmi berhasil disiarkan.', 'success'); }; // Eksekusi Update Website & Tema const handleExecuteUpdateWebsite = (e: React.FormEvent) => { e.preventDefault(); setIsUpdatingSite(true); setTimeout(() => { const now = new Date(); const timestampString = now.toLocaleDateString('id-ID', { day: '2-digit', month: 'short', year: 'numeric' }) + `, ${now.toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit' })} WIB`; setActiveTheme(tempTheme); setSiteConfig({ ...tempConfig, lastUpdated: timestampString }); setIsUpdatingSite(false); showToast('Website & Tema berhasil diperbarui secara langsung!', 'success'); }, 800); }; const handleResetThemeDefault = () => { setTempTheme('emerald'); setTempConfig({ schoolName: 'MA MAMBAUL HIKMAH', subTitle: 'Sistem Informasi Data Pokok Madrasah & Ekosistem IT', heroTitle: 'Integrasi Layanan Data & Ekosistem Digital Madrasah', heroSubtitle: 'Portal resmi pengelolaan data Guru & Tenaga Kependidikan (GTK), akses server Rapor Digital Madrasah (RDM), serta pengaduan verval data peserta didik secara langsung.', runningAnnouncement: 'Selamat datang di Portal Operator MA Mambaul Hikmah. Layanan data terpadu EMIS 4.0, SIMPATIKA, & RDM Aktif.', whatsappNumber: '6281234567890', lastUpdated: siteConfig.lastUpdated }); showToast('Draf pengaturan telah dikembalikan ke standar.', 'info'); }; const handleLoginSubmit = (e: React.FormEvent) => { e.preventDefault(); if (loginEmail === 'operator@madrasah.sch.id' && loginPassword === 'operator123') { setIsAdminLoggedIn(true); setCurrentView('admin'); setLoginError(''); showToast('Otorisasi Root Operator Disetujui!', 'success'); } else { setLoginError('Kredensial tidak valid. Silakan gunakan akun demo.'); } }; const handleLogout = () => { setIsAdminLoggedIn(false); setCurrentView('public'); showToast('Sesi operator telah ditutup dengan aman.', 'info'); }; const filteredAdminGtk = gtkList.filter( (gtk) => gtk.nama.toLowerCase().includes(adminGtkSearch.toLowerCase()) || gtk.nuptk.includes(adminGtkSearch) || gtk.npk.includes(adminGtkSearch) || gtk.mapel.toLowerCase().includes(adminGtkSearch.toLowerCase()) || gtk.passwordEmisGtk.toLowerCase().includes(adminGtkSearch.toLowerCase()) ); if (currentView === 'login') { return (

Otorisasi Operator

Panel Kendali Data {siteConfig.schoolName}

{loginError && (
{loginError}
)}
setLoginEmail(e.target.value)} className="w-full pl-11 pr-4 py-3 rounded-xl bg-slate-900/80 border border-slate-700/80 focus:outline-none focus:border-slate-500 text-slate-100 text-sm placeholder:text-slate-600" placeholder="operator@madrasah.sch.id" />
setLoginPassword(e.target.value)} className="w-full pl-11 pr-4 py-3 rounded-xl bg-slate-900/80 border border-slate-700/80 focus:outline-none focus:border-slate-500 text-slate-100 text-sm placeholder:text-slate-600" placeholder="••••••••" />

Demo Akses Cepat: operator@madrasah.sch.id / operator123

); } return (
{/* RUNNING TEXT ANNOUNCEMENT BANNER */} {siteConfig.runningAnnouncement && (
PENGUMUMAN SINKRONISASI
{siteConfig.runningAnnouncement}
Terakhir Diperbarui: {siteConfig.lastUpdated}
)} {/* Toast Notification */} {toast.show && (
{toast.type === 'success' && } {toast.type === 'error' && } {toast.type === 'info' && } {toast.message}
)} {/* MODAL LIGHTBOX FOTO */} {previewModalPhoto && (
{previewModalPhoto.title}
{previewModalPhoto.category} {previewModalPhoto.date}

{previewModalPhoto.title}

{previewModalPhoto.caption}

)} {/* MODAL RINCIAN PROFIL GTK (PUBLIK / DETAIL) */} {selectedGtkModal && (
{selectedGtkModal.nama.charAt(0)}
{selectedGtkModal.statusPegawai}

{selectedGtkModal.nama}

{selectedGtkModal.jabatan}

NUPTK Resmi {selectedGtkModal.nuptk}
NPK (Nomor Pendidik Kemenag) {selectedGtkModal.npk}
{/* KOLOM PASSWORD EMIS GTK */}
Password EMIS GTK {isAdminLoggedIn && ( )}
{isAdminLoggedIn ? ( {selectedGtkModal.passwordEmisGtk || 'Belum diatur'} ) : ( Diarsipkan secara aman oleh Operator Madrasah. )}
Mata Pelajaran Diampu {selectedGtkModal.mapel}
Beban Mengajar Mingguan {selectedGtkModal.jtm} JTM / Minggu
Status Sertifikasi Guru {selectedGtkModal.sertifikasi}
Keaktifan SIMPATIKA Kemenag {selectedGtkModal.statusSimpatika}
Pendidikan Terakhir {selectedGtkModal.pendidikan}
TMT Pendidik {selectedGtkModal.tmt}
Data tersinkronisasi dengan EMIS GTK & SIMPATIKA
)} {/* MODAL FORM GTK (TAMBAH / EDIT) */} {showGtkFormModal && (

{isEditingGtk ? 'Perbarui Data Guru & Tenaga Pendidik' : 'Tambah GTK Baru ke Database'}

Data ini akan tampil pada pencarian guru mandiri (EMIS GTK) dan rekapitulasi operator.

setCurrentGtkForm({ ...currentGtkForm, nama: e.target.value })} placeholder="Cth: Drs. H. Ahmad Fauzi, M.Pd.I" className="w-full px-4 py-2.5 rounded-xl bg-slate-900 border border-slate-700 text-white text-xs focus:border-slate-500 focus:outline-none" />
setCurrentGtkForm({ ...currentGtkForm, nuptk: e.target.value })} placeholder="16 digit NUPTK (atau -)" className="w-full px-4 py-2.5 rounded-xl bg-slate-900 border border-slate-700 text-white text-xs focus:border-slate-500 focus:outline-none" />
setCurrentGtkForm({ ...currentGtkForm, npk: e.target.value })} placeholder="NPK aktif pendidik" className="w-full px-4 py-2.5 rounded-xl bg-slate-900 border border-slate-700 text-white text-xs focus:border-slate-500 focus:outline-none" />
setCurrentGtkForm({ ...currentGtkForm, passwordEmisGtk: e.target.value })} placeholder="Password EMIS GTK" className={`w-full px-4 py-2.5 rounded-xl bg-slate-900 border ${theme.accentBorder} ${theme.accentText} font-mono text-xs focus:outline-none`} />
setCurrentGtkForm({ ...currentGtkForm, mapel: e.target.value })} placeholder="Cth: Matematika / Fiqih" className="w-full px-4 py-2.5 rounded-xl bg-slate-900 border border-slate-700 text-white text-xs focus:border-slate-500 focus:outline-none" />
setCurrentGtkForm({ ...currentGtkForm, jabatan: e.target.value })} placeholder="Cth: Guru MP / Wali Kelas" className="w-full px-4 py-2.5 rounded-xl bg-slate-900 border border-slate-700 text-white text-xs focus:border-slate-500 focus:outline-none" />
setCurrentGtkForm({ ...currentGtkForm, jtm: parseInt(e.target.value, 10) || 0 })} className="w-full px-4 py-2.5 rounded-xl bg-slate-900 border border-slate-700 text-white text-xs focus:border-slate-500 focus:outline-none" />
setCurrentGtkForm({ ...currentGtkForm, pendidikan: e.target.value })} placeholder="Cth: S1 Pendidikan Agama Islam" className="w-full px-4 py-2.5 rounded-xl bg-slate-900 border border-slate-700 text-white text-xs focus:border-slate-500 focus:outline-none" />
setCurrentGtkForm({ ...currentGtkForm, tmt: e.target.value })} placeholder="Cth: 01 Juli 2018" className="w-full px-4 py-2.5 rounded-xl bg-slate-900 border border-slate-700 text-white text-xs focus:border-slate-500 focus:outline-none" />
)} {/* HEADER */}
setCurrentView('public')}>

{siteConfig.schoolName}

PORTAL OPERATOR

{siteConfig.subTitle}

{timeString || 'WIB'}
{isAdminLoggedIn ? (
) : ( )}
{currentView === 'admin' && isAdminLoggedIn ? ( /* ================= ADMIN CONSOLE WORKSPACE ================= */
Sesi Root Operator Madrasah Aktif

Console Kelola Data Pokok & Tampilan

Akses tingkat tinggi untuk administrasi GTK, posting edaran, galeri, dan kustomisasi tema website.

{/* TAB UPDATE WEBSITE */}
{/* TAB 1: DATABASE GTK TABLE */} {adminTab === 'database-gtk' && (
setAdminGtkSearch(e.target.value)} placeholder="Cari NUPTK, NPK, nama guru, password, atau mapel..." className="w-full pl-10 pr-4 py-2.5 rounded-xl bg-slate-900 border border-slate-800 text-xs text-white focus:border-slate-600 focus:outline-none" />
{filteredAdminGtk.map((gtk) => { const isPassVisible = visiblePasswords[gtk.id]; return ( {/* TAMPILAN PASS EMIS GTK DEGAN VISIBILITY & COPY */} ); })}
Nama Pendidik NUPTK / NPK Password EMIS GTK Mata Pelajaran Status Pegawai Sertifikasi Aksi Operasional
{gtk.nama}
{gtk.jabatan}
{gtk.nuptk}
NPK: {gtk.npk}
{isPassVisible ? ( gtk.passwordEmisGtk || '-' ) : ( '••••••••' )}
{gtk.mapel} {gtk.statusPegawai} {gtk.sertifikasi}
)} {/* TAB 2: UPLOAD FOTO GALERI */} {adminTab === 'upload-foto' && (

Upload Foto Dokumentasi Kegiatan

Publikasikan dokumentasi server, kegiatan asesmen, atau rapat operator ke galeri publik.

setNewPhotoTitle(e.target.value)} placeholder="Cth: Monitoring Jaringan CBT Asesmen Madrasah" className="w-full px-4 py-2.5 rounded-xl bg-slate-900 border border-slate-700 text-xs text-white focus:border-slate-500 focus:outline-none" />
{newPhotoPreview && (

Pratinjau Gambar:

Preview
)}