import React, { useState, useEffect } from 'react'; const App = () => { const [activeTab, setActiveTab] = useState('belajar'); const [userName, setUserName] = useState(''); const [isLoggedIn, setIsLoggedIn] = useState(false); if (!isLoggedIn) { return (
🤖

Petualangan Loopy

Siap belajar Loop (Perulangan)? Masukkan nama lengkapmu dulu yuk!

{ e.preventDefault(); if(userName.trim() !== '') setIsLoggedIn(true); }}> setUserName(e.target.value)} className="w-full px-4 py-4 rounded-xl border-2 border-indigo-200 focus:outline-none focus:border-indigo-500 mb-6 text-xl text-center shadow-inner" required />
); } return (
{/* Header */}

🤖 Petualangan Loopy 🔄

Halo, {userName}! Belajar "Loop" itu seru!

{/* Navigation */} {/* Content Area */}
{activeTab === 'belajar' && } {activeTab === 'main' && } {activeTab === 'kuis' && }
); }; // --- SECTION 1: BELAJAR --- const BelajarSection = () => { const [claps, setClaps] = useState([]); const [isLooping, setIsLooping] = useState(false); const manualClap = () => { if (claps.length < 10) setClaps([...claps, '👏']); }; const loopClap = async () => { if (isLooping) return; setIsLooping(true); setClaps([]); // Reset let currentClaps = []; for (let i = 0; i < 5; i++) { await new Promise(r => setTimeout(r, 400)); currentClaps.push('👏'); setClaps([...currentClaps]); } setIsLooping(false); }; return (

Apa itu Loop? 🤔

Loop artinya mengulang!
Bayangkan kamu diminta tepuk tangan 5 kali. Daripada kamu disuruh:
"Tepuk tangan, tepuk tangan, tepuk tangan, tepuk tangan, tepuk tangan"...
Lebih gampang bilang: "Ulangi 5 kali: Tepuk tangan!"

Ayo Buktikan!

Coba bandingkan membuat 5 tepukan secara manual vs menggunakan Loop.

{claps.length === 0 && Belum ada tepukan...} {claps.map((clap, idx) => ( {clap} ))}

Jumlah: {claps.length}

💡 Fakta Komputer: Komputer sangat suka Loop! Komputer tidak pernah capek disuruh mengulang perintah ribuan kali.

); }; // --- SECTION 2: GAME --- const GameSection = () => { const [robotPos, setRobotPos] = useState(0); const targetPos = 5; const [loopCount, setLoopCount] = useState(1); const [isRunning, setIsRunning] = useState(false); const [message, setMessage] = useState("Bantu Loopy mengambil baterai hijau!"); const [status, setStatus] = useState("idle"); // idle, success, fail const runProgram = async () => { if (isRunning) return; setIsRunning(true); setMessage("Menjalankan Loop..."); setStatus("idle"); setRobotPos(0); for (let i = 1; i <= loopCount; i++) { await new Promise(r => setTimeout(r, 600)); // Jeda agar animasi terlihat setRobotPos(i); } setIsRunning(false); // Cek hasil if (loopCount === targetPos) { setMessage("Horeee! 🎉 Loopy berhasil dapat baterainya!"); setStatus("success"); } else if (loopCount < targetPos) { setMessage("Yah.. Loopy berhenti di tengah jalan. Langkahnya kurang! 😢"); setStatus("fail"); } else { setMessage("Waduh! Loopy kebablasan jalannya! Kebanyakan langkah! 💥"); setStatus("fail"); } }; const resetGame = () => { setRobotPos(0); setMessage("Bantu Loopy mengambil baterai hijau!"); setStatus("idle"); setLoopCount(1); } // Membuat grid jalanan const grid = Array.from({ length: 7 }, (_, i) => i); return (

Misi: Ambil Baterai! 🔋

{message}

{/* Grid Animasi */}
{grid.map((pos) => (
{pos === targetPos && status !== 'success' && 🔋} {pos === robotPos && ( {status === 'success' ? '🥳' : status === 'fail' ? '😵' : '🤖'} )}
))}
{/* Control Panel */}
Ulangi kali:
👉 Jalan Maju 1 Langkah
); }; // --- SECTION 3: KUIS --- const KuisSection = ({ userName }) => { const [currentQ, setCurrentQ] = useState(0); const [score, setScore] = useState(0); const [showResult, setShowResult] = useState(false); const questions = [ { q: "Apa sebutan lain dari 'Loop' dalam bahasa Indonesia?", opts: ["Perulangan", "Pencabangan", "Penjumlahan"], ans: 0 }, { q: "Mengapa kita menggunakan Loop dalam memprogram komputer?", opts: ["Biar komputer cepat rusak", "Agar tidak capek menulis perintah yang sama berulang-ulang", "Supaya layarnya warna-warni"], ans: 1 }, { q: "Jika kamu ingin robot maju 10 langkah, perintah mana yang benar?", opts: ["Tulis 'Maju' sebanyak 10 baris", "Ulangi 1 kali: [Maju 10]", "Ulangi 10 kali: [Maju]"], ans: 2 }, { q: "Apa yang membuat komputer sangat cocok untuk melakukan tugas Loop?", opts: ["Komputer bisa tidur", "Komputer tidak pernah merasa bosan atau capek mengulang", "Komputer suka bermain game"], ans: 1 }, { q: "Jika perintahnya adalah 'Ulangi 3 kali: [Lompat, Jongkok]', berapa kali total kamu akan Jongkok?", opts: ["1 kali", "3 kali", "6 kali"], ans: 1 }, { q: "Di antara kegiatan ini, mana yang merupakan contoh Loop di kehidupan sehari-hari?", opts: ["Makan permen 1 kali", "Membaca 1 halaman buku", "Mengayuh pedal sepeda berulang kali"], ans: 2 }, { q: "Apa bahasa Inggris dari 'Perulangan'?", opts: ["Loop", "Jump", "Run"], ans: 0 }, { q: "Jika kamu disuruh menulis angka 1 sampai 100, lebih cepat pakai cara apa?", opts: ["Menulis manual dengan tangan", "Menyuruh teman menuliskannya", "Pakai perintah Loop di komputer"], ans: 2 }, { q: "Gambar sebuah kotak persegi punya 4 sisi. Perintah Loop apa yang cocok untuk menggambar kotak?", opts: ["Ulangi 4 kali: [Maju, Belok]", "Ulangi 1 kali: [Kotak]", "Ulangi 2 kali: [Maju]"], ans: 0 }, { q: "Apa yang terjadi jika kita menyuruh komputer mengulang tanpa henti (Loop selamanya)?", opts: ["Komputernya jadi lebih cepat", "Komputernya akan terus bekerja tanpa henti/hang", "Komputernya akan meledak"], ans: 1 } ]; const handleAnswer = (optIndex) => { if (optIndex === questions[currentQ].ans) { setScore(score + 1); } if (currentQ < questions.length - 1) { setCurrentQ(currentQ + 1); } else { setShowResult(true); } }; const restartQuiz = () => { setCurrentQ(0); setScore(0); setShowResult(false); }; if (showResult) { return (

{score === questions.length ? '🌟 Sempurna! 🌟' : 'Kerja Bagus! 👍'}

Skor kamu: {score} dari {questions.length}

{score === questions.length ? (

Wah, Kak {userName} sudah jadi ahli Loop nih! Keren banget!

) : (

Kak {userName} sudah hebat, yuk coba lagi biar dapat bintang penuh!

)}
); } const q = questions[currentQ]; return (

Pertanyaan {currentQ + 1} / {questions.length}

⭐ Skor: {score}

{q.q}

{q.opts.map((opt, idx) => ( ))}
); }; export default App;