// Show/hide password — mobile typo insurance (no confirm field to catch them)
const pwInput = document.getElementById('pwInput');
const pwToggle = document.getElementById('pwToggle');
pwToggle.addEventListener('click', () => {
const show = pwInput.type === 'password';
pwInput.type = show ? 'text' : 'password';
pwToggle.textContent = show ? 'Hide' : 'Show';
pwToggle.setAttribute('aria-label', show ? 'Hide password' : 'Show password');
});
document.getElementById('registerForm').addEventListener('submit', async (e) => {
e.preventDefault();
const btn = document.getElementById('submitBtn');
const error = document.getElementById('error');
btn.disabled = true; btn.textContent = 'Creating...';
error.style.display = 'none';
try {
const form = new FormData(e.target);
const res = await fetch('/api/auth/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: form.get('email'), password: form.get('password'),
firstName: form.get('firstName'), lastName: form.get('lastName'),
companyName: form.get('companyName'),
// Where they came from. Server sanitizes and may discard it;
// a missing or unreadable stash must never block signup.
firstTouch: (function () {
try { return JSON.parse(localStorage.getItem('hsFirstTouch') || 'null'); }
catch (_) { return null; }
})(),
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
// Two-stage confirmation: verify email first, then admin
// approval. The card swaps to a "check your inbox" state.
document.getElementById('card').innerHTML = `
Check your email
We sent a verification link to
${form.get('email')}.
${data.needsApproval
? `Click it to confirm your address — then an admin will review your account and you'll get a second email when you're approved.`
: `Click it to confirm your address, then log in and you're ready to get started.`}