import React, { useState, useRef, useEffect } from 'react';
import { BookOpen, Code, GraduationCap, MessageSquare, CheckCircle, ChevronRight, Play, Award, Star, Menu, X, Printer, Download, User, AlertTriangle, Send, Settings, Edit, Trash2, ListChecks } from 'lucide-react';
// Fungsi utama komponen aplikasi
const App = () => {
// State utama
const [activeTab, setActiveTab] = useState('modules');
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const [userName, setUserName] = useState('');
const [isCertified, setIsCertified] = useState(false);
// State untuk Role Management (FITUR ADMIN BARU)
const [userRole, setUserRole] = useState('user'); // 'user' atau 'admin'
const isAdmin = userRole === 'admin';
// --- Data Modul Pelatihan ---
const initialModules = [
{
id: 1,
title: "Pengenalan Gemini AI",
duration: "15 Menit",
level: "Dasar",
description: "Memahami apa itu Gemini, bagaimana cara kerjanya, dan etika penggunaan AI dalam pendidikan.",
content: (
Apa itu Gemini?
Gemini adalah model AI generatif dari Google yang mampu memahami, mengolah, dan menggabungkan berbagai jenis informasi termasuk teks, kode, audio, gambar, dan video.
Perbedaan dengan Mesin Pencari
Google Search: Mencari informasi yang sudah ada.
Gemini: Membuat konten baru, merangkum, dan menganalisis data.
Etika & Halusinasi AI
AI bisa melakukan "halusinasi" (memberikan info salah dengan percaya diri). Guru harus selalu memverifikasi output AI, terutama untuk fakta sejarah atau data saintifik.
)
},
{
id: 2,
title: "Teknik Prompting untuk Guru",
duration: "20 Menit",
level: "Menengah",
description: "Belajar membuat instruksi (prompt) yang efektif untuk mendapatkan hasil RPP, soal, dan materi ajar terbaik.",
content: (
Rumus Prompt Efektif: PREP
P - Persona
Berikan peran. Contoh: "Bertindaklah sebagai Guru Biologi senior..."
R - Request
Tugas spesifik. Contoh: "Buatkan rencana pembelajaran 45 menit tentang fotosintesis."
E - Example
Berikan contoh format. Contoh: "Gunakan format tabel dengan kolom waktu dan aktivitas."
P - Parameter
Batasan. Contoh: "Untuk siswa SMP kelas 7, gaya bahasa santai."
)
}
];
const [modules, setModules] = useState(initialModules);
// Data simulasi kelulusan
const initialCertifications = [
{ id: 101, name: "Siti Aisyah, S.Pd.", date: "2024-11-01", status: "Lulus", quizScore: "90%" },
{ id: 102, name: "Bambang Wijaya, M.Sc.", date: "2024-11-05", status: "Lulus", quizScore: "83%" },
{ id: 103, name: "Nurul Hidayah", date: "2024-11-10", status: "Belum Lulus", quizScore: "65%" },
];
const [certifications, setCertifications] = useState(initialCertifications);
// --- Komponen Halaman Admin (BARU) ---
const AdminPage = () => {
const [adminActiveTab, setAdminActiveTab] = useState('modules');
// State untuk form edit modul
const [editingModule, setEditingModule] = useState(null); // null atau object modul
const [newModuleTitle, setNewModuleTitle] = useState('');
const [newModuleDesc, setNewModuleDesc] = useState('');
const [newModuleDuration, setNewModuleDuration] = useState('');
const [newModuleLevel, setNewModuleLevel] = useState('Dasar');
// Reset form saat tab admin berubah
useEffect(() => {
setEditingModule(null);
}, [adminActiveTab]);
// Handle Edit Modul
const handleEditModule = (mod) => {
setEditingModule(mod.id);
setNewModuleTitle(mod.title);
setNewModuleDesc(mod.description);
setNewModuleDuration(mod.duration);
setNewModuleLevel(mod.level);
};
// Handle Simpan Modul
const handleSaveModule = () => {
if (!newModuleTitle || !newModuleDesc || !newModuleDuration) {
// Mengganti alert() dengan UI pesan khusus di masa depan, tapi untuk saat ini menggunakan alert sederhana
window.alert("Semua kolom harus diisi!");
return;
}
if (editingModule === 'new') {
// Tambah Modul Baru
const newId = Math.max(...modules.map(m => m.id), 0) + 1;
const newMod = {
id: newId,
title: newModuleTitle,
description: newModuleDesc,
duration: newModuleDuration,
level: newModuleLevel,
content:
Konten modul baru. Silakan edit langsung di kode sumber atau kembangkan fungsionalitas editor lebih lanjut.
};
setModules([...modules, newMod]);
} else {
// Edit Modul Existing
setModules(modules.map(mod =>
mod.id === editingModule ? {
...mod,
title: newModuleTitle,
description: newModuleDesc,
duration: newModuleDuration,
level: newModuleLevel
} : mod
));
}
// Reset form
setEditingModule(null);
setNewModuleTitle('');
setNewModuleDesc('');
setNewModuleDuration('');
setNewModuleLevel('Dasar');
};
// Handle Hapus Modul
const handleDeleteModule = (id) => {
// Menggunakan window.confirm() sebagai placeholder untuk modal kustom.
if (window.confirm("Apakah Anda yakin ingin menghapus modul ini?")) {
setModules(modules.filter(mod => mod.id !== id));
}
};
// Komponen Daftar Modul
const ModuleManagement = () => (
Daftar Modul Pelatihan ({modules.length})
{/* Form Edit/Tambah Modul */}
{(editingModule !== null) && (
{editingModule === 'new' ? 'Tambah Modul Baru' : `Edit Modul ID: ${editingModule}`}
Telah berhasil menyelesaikan pelatihan intensif "Pemanfaatan Gemini AI untuk Pendidikan".
Peserta telah menunjukkan kompetensi dalam Prompt Engineering, Penyusunan RPP Otomatis, dan Etika AI.
Rizky Dev
Lead Instructor
{/* Seal */}
{today}
Tanggal Terbit
{/* Opsi Cetak & Kirim Email - Hanya terlihat di layar */}
Opsi Unduh & Kirim
{/* Tombol Cetak/PDF */}
PENTING (Untuk Pengguna HP):
Setelah klik tombol di atas, pastikan Anda **mengganti tujuan printer** (di bagian atas dialog) menjadi **"Simpan sebagai PDF"** agar file tersimpan di perangkat Anda.
);
};
const SimulatorPage = () => {
const [input, setInput] = useState('');
const [output, setOutput] = useState(null);
const [loading, setLoading] = useState(false);
// Simulasi respons AI sederhana untuk tujuan demo
const handleSimulate = () => {
if (!input.trim()) return;
setLoading(true);
// Delay palsu untuk efek "berpikir"
setTimeout(() => {
let response = "";
const lowerInput = input.toLowerCase();
if (lowerInput.includes('rpp') || lowerInput.includes('rencana')) {
response = `**Rencana Pelaksanaan Pembelajaran (Simulasi)**\n\n**Topik:** ${input}\n**Kelas:** 7 SMP\n**Durasi:** 2 x 40 Menit\n\n1. **Tujuan Pembelajaran:** Siswa dapat memahami konsep dasar sesuai topik.\n2. **Kegiatan Inti:**\n - Guru menampilkan video pemantik.\n - Diskusi kelompok (20 menit).\n - Presentasi hasil diskusi.\n3. **Penilaian:** Observasi keaktifan dan tes tulis singkat.`;
} else if (lowerInput.includes('soal') || lowerInput.includes('kuis')) {
response = `**Draf Soal Kuis (Simulasi)**\n\nBerikut adalah 3 contoh soal pilihan ganda berdasarkan topik yang Anda minta:\n\n1. Apa penyebab utama terjadinya peristiwa tersebut?\n a. Faktor A\n b. Faktor B\n c. Faktor C\n\n2. Manakah di bawah ini yang bukan termasuk karakteristik utama?\n\n*Catatan: Ini adalah simulasi. Di platform asli, Gemini akan menghasilkan konten yang jauh lebih mendalam.*`;
} else {
response = "Ini adalah respons simulasi dari Gemini. Dalam versi nyata, saya akan memberikan jawaban mendalam tentang: " + input + "\n\nCoba gunakan kata kunci 'RPP' atau 'Soal' untuk melihat format spesifik.";
}
setOutput(response);
setLoading(false);
}, 1500);
};
return (
Simulator Prompting (Praktik)
Latih kemampuan prompting Anda di lingkungan yang aman sebelum menggunakan akun asli.
{/* Header Simulator */}
Gemini Ed-Sim v1.0
Mode Latihan
{/* Area Output */}
{output ? (
G
{output}
) : (
Output AI akan muncul di sini...
)}
{loading && (
G
)}
{/* Area Input */}
Tips: Gunakan rumus Persona, Request, Example, Parameter untuk hasil terbaik.
);
};
const QuizPage = () => {
const [currentQ, setCurrentQ] = useState(0);
const [score, setScore] = useState(0);
const [finished, setFinished] = useState(false);
const questions = [
{
q: "Manakah kegunaan paling tepat Gemini untuk guru?",
options: ["Menggantikan peran guru di kelas", "Membantu membuat draf RPP dan ide materi", "Menghukum siswa otomatis", "Mencari jawaban ujian nasional bocoran"],
a: 1
},
{
q: "Apa yang dimaksud dengan 'Halusinasi AI'?",
options: ["AI bisa melihat hantu", "AI memberikan jawaban yang terdengar meyakinkan tapi faktanya salah", "AI menjadi sangat pintar", "AI menolak menjawab pertanyaan"],
a: 1
},
{
q: "Dalam prompting, huruf 'P' pertama dalam PREP berarti?",
options: ["Prompt", "Persona (Peran)", "Power", "Program"],
a: 1
}
];
const handleAnswer = (index) => {
if (index === questions[currentQ].a) {
setScore(score + 1);
}
if (currentQ < questions.length - 1) {
setCurrentQ(currentQ + 1);
} else {
setFinished(true);
}
};
if (finished) {
return (
### Fitur Utama yang Telah Diterapkan:
1. **Skor Real-time**: Menggunakan Firebase Firestore `onSnapshot`. Artinya, jika ada siswa lain yang menyelesaikan kuis di perangkat berbeda, nama mereka akan langsung muncul di *Leaderboard* tanpa perlu memuat ulang halaman (refresh).
2. **Skor Pribadi & Tim**: Aplikasi merekam skor setiap individu, namun juga melakukan agregasi otomatis untuk menampilkan total poin berdasarkan Nama Tim yang dimasukkan.
3. **Responsif**: Layout otomatis menyesuaikan ukuran layar, sangat nyaman dibuka di HP maupun Laptop.
4. **Admin Mode**: Saya menyertakan tombol gerigi di pojok kanan atas untuk masuk ke menu Admin guna mereset skor jika Anda ingin memulai kuis baru (misalnya ganti sesi kelas).
**Catatan:** Untuk penggunaan di blog publik, pastikan pengaturan Firebase Anda sudah benar. Jika Anda ingin kuis ini lebih aman (misal: hanya user terdaftar yang bisa ikut), kita bisa meningkatkan sistem autentikasinya di masa mendatang.
Apakah ada bagian soal atau desain yang ingin Anda ubah?
Mempercantik Blog Menggunakan Template Pihak Ketiga
Meskipun konten adalah raja, tetapi tampilan blog yang cantik atau ciamik menjadi daya tarik tersendiri bagi pengunjung untuk datang kembali mengunjungi blog kita.
Saat ini pun sebenarnya template bawaan blogger yang terbaru sangat bagus dibandingkan template bawaan sebelumnya. Dengan menggunakan template yang baru kita sudah tidak memikirkan artikel menjadi terlihat panjang meski tanpa di jump break, karena readmore-nya dah otomatis. Demikian juga, template blogger yang terbaru bersifat responsif yang artinya dibuka dengan perangkat apapun langsung menyesuaikan diri ukurannya.
Template blogger contempo
Selain template blogger contempo yang responsif, ada juga pilihan lain seperti soho, emprio, serta notable. Dan setiap jenis template itu ad 5 variasi. Sehingga bagi pengguna blogger bisa menggunakan 20 variasi template yang berbeda.
Tetapi, bagaimana jika sudah bosan atau butuh style yang lebih banyak? Tentunya kita bisa mengoprek template baru tersebut maupun menggunakan template pihak ketiga.
Postingan kali ini, kita akan coba untuk menggunakan layanan template pihak ketiga. Kita bisa mencari ribuan template di btemplates, gooyaabitemplates, Templateism dan banyak penyedia layanan template lainnya baik yang gratis maupun berbayar.
Mula-mula buka dulu btemplates.com
Dari ribuan template yang ada, misalnya pilih template GreatMag dengan cara meng-kliknya.
Template GreatMag ini merupakan template dengan 1 Sidebar, 2 kolom serta memiliki 3 kolom pada bagian footer. Template ini sebuah template yang diadaptasi dari Wordpress yang memiliki slider, responsif, breadcrumb dan berbagai fitur lain. Oke, klik saja Live Demo untuk melihat tampilannya atau langsung saja klil Free Download.
Template yang sudah terdownload (bisa dilihat di file manager-download), kita ekstraks terus perhatikan disitu ada file GreatMag.xml seperti pada gambar berikut.
File ini bisa dibuka dengan menggunakan notepad, wordpad, ms word, adobe dremaweaver dan lainnya untuk melihat kode dari template tersebut.
Untuk mengganti template yang sudah ada, ada 2 cara yaitu dengan meng-copy paste isi file tersebut yang sebelumnya sudah dibuka, misalnya dengan notepad atau dengan mengupload file tersebut ke theme dengan cara buka dasboard blogger.com.
Backup digunakan untuk memback-up atau menyimpan template yang yang sudah terpasang. Jika kita seringkali berganti template, untuk menghindari hal-hal yang tidak diinginkan silahkan template yang ada dibackup dulu.
Restore ini yang akan digunakan untuk mengganti template yang ada dengan yang baru dengan cara nanti diupload.
Switch to first generation Classing theme jika ingin beralih ke template lama/klasik.
Edit html digunakan untuk mengedit template secara langsung, termasuk jika memakai copy paste.
Kita klik Restore, silahkan Upload, cari file GreatMag.xml tadi..tunggu sebentar.
Jika sudah selesai, kemudian klik view blog. Taraaaa....blog Anda sudah menjadi lebih cantik kan ya? Silahkan untuk berganti-ganti template semaunya tetapi jangan lupa untuk rutin posting.
Tetap ingat bahwa, "konten adalah raja".
Tampilan sebelumnya
Tampilan sesudahnya
Pada postingan berikutnya, kita akan coba mulai menguprek template yang ada agar sesuai dengan harapan kita. Selamat mencoba..dan siap-siap menjadi blogger.