196 lines
5.8 KiB
JavaScript
196 lines
5.8 KiB
JavaScript
// ===== PARTICLES BACKGROUND =====
|
|
function createParticles() {
|
|
const container = document.getElementById('particles');
|
|
if (!container) return;
|
|
|
|
const count = 30;
|
|
for (let i = 0; i < count; i++) {
|
|
const particle = document.createElement('div');
|
|
particle.classList.add('particle');
|
|
particle.style.left = Math.random() * 100 + '%';
|
|
particle.style.width = (Math.random() * 2 + 1) + 'px';
|
|
particle.style.height = particle.style.width;
|
|
particle.style.animationDuration = (Math.random() * 15 + 10) + 's';
|
|
particle.style.animationDelay = (Math.random() * 10) + 's';
|
|
particle.style.opacity = Math.random() * 0.3 + 0.05;
|
|
container.appendChild(particle);
|
|
}
|
|
}
|
|
|
|
// ===== TOGGLE PASSWORD VISIBILITY =====
|
|
function togglePassword(inputId, toggleEl) {
|
|
const input = document.getElementById(inputId);
|
|
if (!input) return;
|
|
|
|
if (input.type === 'password') {
|
|
input.type = 'text';
|
|
toggleEl.classList.add('active');
|
|
} else {
|
|
input.type = 'password';
|
|
toggleEl.classList.remove('active');
|
|
}
|
|
}
|
|
|
|
// ===== TOAST NOTIFICATIONS =====
|
|
function showToast(message, type = 'info') {
|
|
// Remove existing toasts
|
|
document.querySelectorAll('.toast').forEach(t => t.remove());
|
|
|
|
const toast = document.createElement('div');
|
|
toast.className = `toast ${type}`;
|
|
toast.textContent = message;
|
|
document.body.appendChild(toast);
|
|
|
|
// Trigger reflow for animation
|
|
toast.offsetHeight;
|
|
toast.classList.add('show');
|
|
|
|
setTimeout(() => {
|
|
toast.classList.remove('show');
|
|
setTimeout(() => toast.remove(), 400);
|
|
}, 3000);
|
|
}
|
|
|
|
// ===== BUTTON LOADING STATE =====
|
|
function setLoading(btn, loading) {
|
|
const text = btn.querySelector('.btn-text');
|
|
const loader = btn.querySelector('.btn-loader');
|
|
|
|
if (loading) {
|
|
text.style.display = 'none';
|
|
loader.style.display = 'inline-flex';
|
|
btn.disabled = true;
|
|
btn.style.pointerEvents = 'none';
|
|
} else {
|
|
text.style.display = 'inline';
|
|
loader.style.display = 'none';
|
|
btn.disabled = false;
|
|
btn.style.pointerEvents = 'auto';
|
|
}
|
|
}
|
|
|
|
// ===== LOGIN HANDLER =====
|
|
function handleLogin(e) {
|
|
e.preventDefault();
|
|
|
|
const email = document.getElementById('loginEmail').value.trim();
|
|
const password = document.getElementById('loginPassword').value;
|
|
const btn = document.getElementById('loginBtn');
|
|
|
|
if (!email || !password) {
|
|
showToast('Silakan isi semua field', 'error');
|
|
return;
|
|
}
|
|
|
|
setLoading(btn, true);
|
|
|
|
// Simulate login process
|
|
setTimeout(() => {
|
|
setLoading(btn, false);
|
|
showToast('Login berhasil! Mengalihkan...', 'success');
|
|
|
|
// Redirect to dashboard
|
|
setTimeout(() => {
|
|
window.location.href = 'dashboard.html';
|
|
}, 1500);
|
|
}, 1800);
|
|
}
|
|
|
|
// ===== REGISTER HANDLER =====
|
|
function handleRegister(e) {
|
|
e.preventDefault();
|
|
|
|
const username = document.getElementById('regUsername').value.trim();
|
|
const email = document.getElementById('regEmail').value.trim();
|
|
const password = document.getElementById('regPassword').value;
|
|
const confirmPassword = document.getElementById('regConfirmPassword').value;
|
|
const btn = document.getElementById('registerBtn');
|
|
|
|
if (!username || !email || !password || !confirmPassword) {
|
|
showToast('Silakan isi semua field', 'error');
|
|
return;
|
|
}
|
|
|
|
if (password.length < 6) {
|
|
showToast('Password minimal 6 karakter', 'error');
|
|
return;
|
|
}
|
|
|
|
if (password !== confirmPassword) {
|
|
showToast('Password dan konfirmasi tidak cocok', 'error');
|
|
return;
|
|
}
|
|
|
|
setLoading(btn, true);
|
|
|
|
// Simulate registration
|
|
setTimeout(() => {
|
|
setLoading(btn, false);
|
|
showToast('Registrasi berhasil! Mengalihkan ke login...', 'success');
|
|
|
|
setTimeout(() => {
|
|
window.location.href = 'login.html';
|
|
}, 1500);
|
|
}, 2000);
|
|
}
|
|
|
|
// ===== PASSWORD MATCH CHECKER =====
|
|
function setupPasswordMatch() {
|
|
const password = document.getElementById('regPassword');
|
|
const confirm = document.getElementById('regConfirmPassword');
|
|
const indicator = document.getElementById('passwordMatch');
|
|
|
|
if (!password || !confirm || !indicator) return;
|
|
|
|
function checkMatch() {
|
|
const pw = password.value;
|
|
const cpw = confirm.value;
|
|
|
|
if (cpw.length === 0) {
|
|
indicator.style.display = 'none';
|
|
return;
|
|
}
|
|
|
|
indicator.style.display = 'flex';
|
|
|
|
if (pw === cpw) {
|
|
indicator.className = 'password-match-indicator match';
|
|
indicator.querySelector('.match-icon').textContent = '✓';
|
|
indicator.querySelector('.match-text').textContent = 'Password cocok';
|
|
} else {
|
|
indicator.className = 'password-match-indicator no-match';
|
|
indicator.querySelector('.match-icon').textContent = '✗';
|
|
indicator.querySelector('.match-text').textContent = 'Password tidak cocok';
|
|
}
|
|
}
|
|
|
|
password.addEventListener('input', checkMatch);
|
|
confirm.addEventListener('input', checkMatch);
|
|
}
|
|
|
|
// ===== INPUT FOCUS ANIMATIONS =====
|
|
function setupInputAnimations() {
|
|
document.querySelectorAll('.input-group input').forEach(input => {
|
|
input.addEventListener('focus', () => {
|
|
input.parentElement.style.transform = 'translateY(-1px)';
|
|
});
|
|
|
|
input.addEventListener('blur', () => {
|
|
input.parentElement.style.transform = 'translateY(0)';
|
|
});
|
|
});
|
|
}
|
|
|
|
// ===== INIT =====
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
createParticles();
|
|
setupPasswordMatch();
|
|
setupInputAnimations();
|
|
});
|
|
|
|
setTimeout(() => {
|
|
const toast = document.querySelector('.toast');
|
|
if(toast){
|
|
toast.classList.remove('show');
|
|
}
|
|
},3000); |