Sewa Kendaraan
Kapan Saja,
Di Mana Saja

Armada lengkap, proses mudah, terpercaya. Verifikasi KTP online, notifikasi realtime.

Verifikasi KTP digital aman
Notifikasi push realtime
Install sebagai aplikasi (PWA)
Transfer & QRIS tersedia

Selamat Datang

Masuk atau buat akun baru untuk mulai menyewa

atau dengan email

Belum punya akun?

atau isi form

Sudah punya akun?

// ── TAB SWITCHER ───────────────────────────────────────── function switchTab(tab) { document.querySelectorAll('.auth-tab').forEach(t => t.classList.remove('active')); document.querySelectorAll('.auth-pane').forEach(p => p.classList.remove('active')); document.getElementById('tab-' + tab).classList.add('active'); document.getElementById('pane-' + tab).classList.add('active'); } // ── TOGGLE PASSWORD VISIBILITY ──────────────────────────── function togglePw(inputId, btn) { const inp = document.getElementById(inputId); const shown = inp.type === 'text'; inp.type = shown ? 'password' : 'text'; btn.innerHTML = shown ? '' : ''; } // ── STRENGTH METER ──────────────────────────────────────── function cekStrength(pw) { let score = 0; if (pw.length >= 6) score++; if (pw.length >= 8) score++; if (/[A-Z]/.test(pw) && /[0-9]/.test(pw)) score++; if (/[^A-Za-z0-9]/.test(pw)) score++; const colors = ['#ef4444','#f59e0b','#22c55e','#16a34a']; const labels = ['Sangat lemah','Lemah','Kuat','Sangat kuat']; for (let i = 1; i <= 4; i++) { const seg = document.getElementById('seg' + i); seg.style.background = i <= score ? colors[score - 1] : '#e2e8f0'; } document.getElementById('strength-label').textContent = pw ? labels[score - 1] || '' : ''; document.getElementById('strength-label').style.color = score > 0 ? colors[score - 1] : '#94a3b8'; } // ── SHOW / HIDE ERROR ──────────────────────────────────── function showErr(id, msg) { const el = document.getElementById(id); el.textContent = msg; el.style.display = 'block'; } function hideErr(id) { document.getElementById(id).style.display = 'none'; } // ── LOADING STATE ───────────────────────────────────────── function setLoading(btnId, loading, defaultHtml) { const btn = document.getElementById(btnId); btn.disabled = loading; btn.innerHTML = loading ? ' Memproses...' : defaultHtml; } // ── LOGIN EMAIL + PASSWORD ──────────────────────────────── async function doLogin() { hideErr('err-masuk'); const email = document.getElementById('masuk-email').value.trim(); const pass = document.getElementById('masuk-pass').value; if (!email || !pass) { showErr('err-masuk','Isi email dan password terlebih dahulu'); return; } setLoading('btn-masuk', true, ' Masuk'); try { const { user } = await $fb.auth.signInWithEmailAndPassword(email, pass); if (typeof window.initFCM === 'function') window.initFCM(user.uid); if (typeof window.subscribeFCMTopic === 'function') window.subscribeFCMTopic(user.uid, 'all-users'); const u = await $fb.db.doc(`users/${user.uid}`).get().then(d => d.exists ? d.data() : null).catch(() => null); if (user.email === window.ADMIN_EMAIL || u?.isAdmin) { location.href = '/admin.html'; } else { location.href = (u?.ktpStatus === 'terverifikasi' || u?.ktpVerified) ? '/dasbor.html' : '/profil.html#ktp'; } } catch (e) { setLoading('btn-masuk', false, ' Masuk'); const errMap = { 'auth/user-not-found': 'Email tidak terdaftar', 'auth/wrong-password': 'Password salah', 'auth/invalid-email': 'Format email tidak valid', 'auth/too-many-requests': 'Terlalu banyak percobaan. Coba lagi nanti.', 'auth/invalid-credential': 'Email atau password salah', }; showErr('err-masuk', errMap[e.code] || e.message); } } // ── LOGIN GOOGLE ────────────────────────────────────────── async function loginGoogle() { try { const provider = new firebase.auth.GoogleAuthProvider(); const { user, additionalUserInfo } = await $fb.auth.signInWithPopup(provider); if (additionalUserInfo.isNewUser) { await $set(`users/${user.uid}`, { nama: user.displayName || '', email: user.email || '', noHp: user.phoneNumber || '', fotoURL: user.photoURL || '', ktpVerified: false, ktpStatus: 'belum', createdAt: firebase.firestore.FieldValue.serverTimestamp() }); } if (typeof window.initFCM === 'function') window.initFCM(user.uid); if (typeof window.subscribeFCMTopic === 'function') window.subscribeFCMTopic(user.uid, 'all-users'); const u = await $fb.db.doc(`users/${user.uid}`).get().then(d => d.exists ? d.data() : null).catch(() => null); if (user.email === window.ADMIN_EMAIL || u?.isAdmin) { location.href = '/admin.html'; } else { location.href = (u?.ktpStatus === 'terverifikasi' || u?.ktpVerified) ? '/dasbor.html' : '/profil.html#ktp'; } } catch(e) { if (e.code !== 'auth/popup-closed-by-user') { showErr('err-masuk', e.message); showErr('err-daftar', e.message); } } } // ── DAFTAR ──────────────────────────────────────────────── async function doDaftar() { hideErr('err-daftar'); const nama = document.getElementById('daftar-nama').value.trim(); const email = document.getElementById('daftar-email').value.trim(); const hp = document.getElementById('daftar-hp').value.trim(); const pass = document.getElementById('daftar-pass').value; const pass2 = document.getElementById('daftar-pass2').value; if (!nama || !email || !hp || !pass) { showErr('err-daftar','Lengkapi semua field'); return; } if (pass !== pass2) { showErr('err-daftar','Password tidak cocok'); return; } if (pass.length < 6) { showErr('err-daftar','Password minimal 6 karakter'); return; } if (!document.getElementById('syarat').checked) { showErr('err-daftar','Centang persetujuan Syarat & Ketentuan'); return; } setLoading('btn-daftar', true, ' Buat Akun'); try { const { user } = await $fb.auth.createUserWithEmailAndPassword(email, pass); await user.updateProfile({ displayName: nama }); await $set(`users/${user.uid}`, { nama, email, noHp: hp, fotoURL: '', ktpVerified: false, ktpStatus: 'belum', createdAt: firebase.firestore.FieldValue.serverTimestamp() }); if (typeof window.initFCM === 'function') window.initFCM(user.uid); if (typeof window.subscribeFCMTopic === 'function') window.subscribeFCMTopic(user.uid, 'all-users'); if (user.email === window.ADMIN_EMAIL) { location.href = '/admin.html'; } else { location.href = '/profil.html#ktp'; } } catch(e) { setLoading('btn-daftar', false, ' Buat Akun'); const errMap = { 'auth/email-already-in-use': 'Email sudah terdaftar. Gunakan Login.', 'auth/invalid-email': 'Format email tidak valid', 'auth/weak-password': 'Password terlalu lemah (min 6 karakter)', }; showErr('err-daftar', errMap[e.code] || e.message); } } // ── LUPA PASSWORD ───────────────────────────────────────── function showModalLupa() { document.getElementById('lupa-email').value = document.getElementById('masuk-email').value; document.getElementById('overlay-lupa').classList.add('show'); hideErr('err-lupa'); } function tutupModalLupa() { document.getElementById('overlay-lupa').classList.remove('show'); } async function doResetPass() { const email = document.getElementById('lupa-email').value.trim(); if (!email) { showErr('err-lupa','Masukkan email Anda'); return; } try { await $fb.auth.sendPasswordResetEmail(email); showToast('Email Terkirim','Link reset password sudah dikirim. Cek inbox / spam Anda.','success'); tutupModalLupa(); } catch(e) { const errMap = { 'auth/user-not-found': 'Email tidak terdaftar', 'auth/invalid-email': 'Format email tidak valid', }; showErr('err-lupa', errMap[e.code] || e.message); } } // Enter key submit document.addEventListener('keydown', e => { if (e.key === 'Enter') { const activePane = document.querySelector('.auth-pane.active').id; if (activePane === 'pane-masuk') doLogin(); else doDaftar(); } }); // Tutup modal dengan klik di luar document.getElementById('overlay-lupa').addEventListener('click', function(e) { if (e.target === this) tutupModalLupa(); });