diff --git a/assets index/script.js b/assets index/script.js new file mode 100644 index 0000000..5c5ba1a --- /dev/null +++ b/assets index/script.js @@ -0,0 +1,115 @@ +const card = document.getElementById("authCard"); +const loginForm = document.getElementById("loginForm"); +const registerForm = document.getElementById("registerForm"); + +// 1. FUNGSI MENGATUR TINGGI (RESIZE OTOMATIS) +function setHeight() { + const isActive = card.classList.contains("active"); + // Hitung tinggi form yang sedang aktif (termasuk jika ada error box) + const formHeight = isActive ? registerForm.offsetHeight : loginForm.offsetHeight; + + // Terapkan tinggi ke card + card.style.height = formHeight + "px"; +} + +// 2. FUNGSI PINDAH LOGIN <-> REGISTER +function toggleAuth(mode) { + // Reset Error Box saat pindah + document.getElementById("loginError").style.display = "none"; + document.getElementById("regError").style.display = "none"; + + if (mode === 'register') { + card.classList.add("active"); + } else { + card.classList.remove("active"); + } + + // Tunggu animasi slide sebentar, baru resize + setTimeout(setHeight, 50); +} + +// 3. DETEKSI ERROR DARI PHP +window.addEventListener("DOMContentLoaded", function() { + setHeight(); // Set tinggi awal + + const urlParams = new URLSearchParams(window.location.search); + const errorStatus = urlParams.get('error'); + + if (errorStatus === 'gagal') { + const errorBox = document.getElementById("loginError"); + errorBox.innerText = "Username atau Password salah!"; + errorBox.style.display = "block"; + + setHeight(); + window.history.replaceState(null, null, window.location.pathname); + } +}); + +window.addEventListener("resize", setHeight); + +// 4. EFEK GLITTER (HIASAN) +document.addEventListener("DOMContentLoaded", function () { + for (let i = 0; i < 15; i++) { + const g = document.createElement("div"); + g.className = "glitter"; + g.style.setProperty("--x", (Math.random() * 200 - 100) + "px"); + g.style.setProperty("--y", (Math.random() * 200 - 100) + "px"); + g.style.left = (Math.random() * 100) + "%"; + g.style.top = (Math.random() * 100) + "%"; + g.style.animationDelay = (Math.random() * 2) + "s"; + card.appendChild(g); + } +}); + +// ========================================== +// 5. VALIDASI REGISTER (YANG BARU DITAMBAHKAN) +// ========================================== +if (registerForm) { + registerForm.addEventListener("submit", function(event) { + // Tahan pengiriman form ke PHP dulu + event.preventDefault(); + + // Ambil nilai dari inputan (Pastikan ID di HTML sudah sesuai ya!) + const username = document.getElementById("regUser").value; + const email = document.getElementById("regEmail").value; + const password = document.getElementById("regPass").value; + const confirmPassword = document.getElementById("regConfirm").value; + + // Fungsi helper untuk menampilkan error di kotak merah Register + function showError(pesan) { + const errorBox = document.getElementById("regError"); + errorBox.innerText = pesan; + errorBox.style.display = "block"; + setHeight(); // PENTING: Resize kartu agar pesan error muat + } + + // --- Mulai Cek Validasi --- + + // 1. Cek Kosong + if (!username || !email || !password || !confirmPassword) { + showError("Semua field harus diisi!"); + return; + } + + // 2. Cek Format Email + if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { + showError("Format email tidak valid"); + return; + } + + // 3. Cek Panjang Password + if (password.length < 6) { + showError("Password minimal 6 karakter"); + return; + } + + // 4. Cek Kesamaan Password + if (password !== confirmPassword) { + showError("Password dan konfirmasi password tidak cocok"); + return; + } + + // Jika semua aman, baru kirim ke auth.php + this.submit(); + }); +} \ No newline at end of file diff --git a/assets index/style.css b/assets index/style.css new file mode 100644 index 0000000..9d7e49a --- /dev/null +++ b/assets index/style.css @@ -0,0 +1,127 @@ +* { box-sizing: border-box; } + +body { + margin: 0; + font-family: 'Segoe UI', Arial, sans-serif; + background: linear-gradient(135deg, #d9a7ff, #fbc2eb, #a1c4fd); + min-height: 100vh; + display: flex; + justify-content: center; + align-items: center; + overflow-x: hidden; +} + +/* --- 2. CONTAINER KARTU (DENGAN ANIMASI RESIZE) --- */ +.auth-card { + width: 380px; + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(12px); + border-radius: 25px; + box-shadow: 0 10px 30px rgba(0,0,0,0.2); + overflow: hidden; + position: relative; + z-index: 10; + /* PENTING: Transisi halus saat tinggi berubah */ + transition: height 0.4s cubic-bezier(0.25, 1, 0.5, 1); +} + +.form-wrapper { + width: 100%; +} + +.forms-container { + display: flex; + width: 200%; /* Lebar 200% untuk menampung Login & Register berdampingan */ + transition: transform 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55); + align-items: flex-start; +} + +.auth-card.active .forms-container { + transform: translateX(-50%); /* Geser ke kiri untuk menampilkan Register */ +} + +/* --- 3. STYLING FORM --- */ +form { + width: 50%; + flex-shrink: 0; + padding: 40px; + display: flex; + flex-direction: column; + align-items: center; +} + +h2 { + margin: 0 0 10px; + text-align: center; + font-size: 26px; + background: linear-gradient(45deg, purple, hotpink); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +.subtitle { + text-align: center; color: gray; font-size: 14px; margin-bottom: 25px; +} + +label { + font-size: 14px; color: #444; width: 100%; margin-bottom: 6px; font-weight: bold; +} + +input { + width: 100%; padding: 12px; border-radius: 12px; + border: 2px solid #ccc; background: #fafafa; + margin-bottom: 15px; font-size: 14px; transition: 0.3s; +} + +input:focus { outline: none; border-color: purple; background: #fff; box-shadow: 0 0 8px rgba(128, 0, 128, 0.1); } + +/* Tombol */ +.btn-submit { + width: 100%; padding: 14px; + background: linear-gradient(45deg, purple, hotpink); + color: white; border-radius: 15px; border: none; + cursor: pointer; font-size: 16px; font-weight: bold; + transition: 0.25s ease; margin-top: 10px; + box-shadow: 0 4px 15px rgba(128, 0, 128, 0.2); +} +.btn-submit:hover { transform: scale(1.02); } + +/* Link Switch */ +.switch-text { margin-top: 20px; font-size: 14px; color: #555; } +.switch-text a { color: purple; text-decoration: none; font-weight: bold; cursor: pointer; } +.switch-text a:hover { text-decoration: underline; } + +/* --- ERROR BOX (KOTAK MERAH) --- */ +.error-box { + width: 100%; + color: #d8000c; + background: #ffbaba; + border: 1px solid #ff7675; + padding: 12px; + border-radius: 10px; + margin-bottom: 20px; + font-size: 13px; + text-align: center; + display: none; /* Default sembunyi */ + font-weight: bold; + animation: fadeIn 0.3s; +} + +@keyframes fadeIn { + from { opacity: 0; transform: translateY(-10px); } + to { opacity: 1; transform: translateY(0); } +} + +/* Dekorasi Buah */ +.fruit { position: absolute; width: 90px; opacity: 0.85; animation: float 6s infinite ease-in-out, drift 15s infinite linear; pointer-events: none; z-index: 1; } +.f1 { top: 8%; left: 10%; width: 80px; } .f2 { top: 65%; right: 12%; } .f3 { top: 22%; right: 55%; width: 60px; } +.f4 { bottom: 15%; left: 28%; } .f5 { bottom: 10%; right: 30%; width: 70px; } .f6 { top: 40%; left: 50%; } +.f7 { bottom: 30%; left: 15%; width: 50px; } .f8 { top: 75%; right: 40%; } .f9 { top: 50%; left: 80%; width: 85px; } +.f10 { bottom: 20%; right: 5%; } +@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-20px) rotate(6deg); } } +@keyframes drift { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(15px); } } + +/* Glitter */ +.glitter { position: absolute; width: 4px; height: 4px; background: purple; border-radius: 50%; opacity: 0; animation: glitter-burst 2s infinite ease-out; pointer-events: none; z-index: 11; } +@keyframes glitter-burst { 0% { transform: scale(0.4); opacity: 0.9; } 100% { transform: scale(1) translate(var(--x), var(--y)); opacity: 0; } } \ No newline at end of file diff --git a/index.php b/index.php index 5164117..4b4a7ee 100644 --- a/index.php +++ b/index.php @@ -7,137 +7,8 @@ Login & Register - Memory Game + - @@ -198,127 +69,7 @@ input:focus { outline: none; border-color: purple; background: #fff; box-shadow: - + \ No newline at end of file