/* ========================= 전역 상태값 ========================= */ let isIdChecked = false; let checkedUserId = ''; const REGEX = { id: /^[a-zA-Z][a-zA-Z0-9]{3,11}$/, password: /^(?=.*[A-Za-z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$/, name: /^[가-힣a-zA-Z\s]+$/, phone: /^\d{3}-\d{4}-\d{4}$/ }; /* ========================= DOM 로드 후 초기화 ========================= */ document.addEventListener('DOMContentLoaded', () => { initMemberType(); initEmailDomain(); initIdCheck(); initPasswordValidation(); // initNameValidation(); initPhoneFormat(); initFormSubmit(); }); /* ========================= 1. 회원유형 ========================= */ function initMemberType() { const radios = document.querySelectorAll('input[name="memberType"]'); const companyRow = document.querySelector('.company-group'); radios.forEach(radio => { radio.addEventListener('change', () => { if (radio.value === '1') { companyRow.style.display = ''; } else { companyRow.style.display = 'none'; companyRow.querySelectorAll('input').forEach(i => i.value = ''); } }); }); } /* ========================= 2. 이메일 도메인 ========================= */ function initEmailDomain() { const select = document.getElementById('domain_list'); const custom = document.getElementById('custom_domain'); select.addEventListener('change', () => { if (select.value === 'type') { custom.classList.remove('d-none'); custom.required = true; } else { custom.classList.add('d-none'); custom.required = false; custom.value = ''; } }); } /* ========================= 3. 아이디 중복확인 ========================= */ function initIdCheck() { const input = document.getElementById('user_id'); const btn = document.getElementById('btn_id_check'); input.addEventListener('input', () => { isIdChecked = false; checkedUserId = ''; input.readOnly = false; }); btn.addEventListener('click', async () => { const userId = input.value.trim(); if (!userId) { alert('아이디를 입력해주세요.'); input.focus(); return; } if (!REGEX.id.test(userId)) { alert('아이디 형식이 올바르지 않습니다.'); return; } const res = await fetch('/kngil/bbs/join.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'check_id', userId }) }); const data = await res.json(); if (data.available) { alert('사용 가능한 아이디입니다.'); isIdChecked = true; checkedUserId = userId; input.readOnly = true; } else { alert(data.message || '이미 사용 중인 아이디입니다.'); isIdChecked = false; } }); } /* ========================= 4. 휴대폰 인증번호 ========================= */ function initPhoneAuth() { const btn = document.querySelector('.btn-code'); const phoneInput = document.getElementById('user_phone'); const timerEl = document.querySelector('.timer'); btn.addEventListener('click', async () => { const phone = phoneInput.value.trim(); if (!/^\d{3}-\d{4}-\d{4}$/.test(phone)) { alert('휴대폰 번호 형식이 올바르지 않습니다.'); return; } await fetch('/api/send_sms.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ phone }) }); startTimer(timerEl, 180); alert('인증번호가 발송되었습니다.'); }); } function startTimer(el, seconds) { clearInterval(authTimer); el.classList.remove('d-none'); let remain = seconds; authTimer = setInterval(() => { const m = String(Math.floor(remain / 60)).padStart(2, '0'); const s = String(remain % 60).padStart(2, '0'); el.textContent = `${m}:${s}`; remain--; if (remain < 0) { clearInterval(authTimer); el.textContent = '만료'; } }, 1000); } /* ========================= 5. 비밀번호 검증 ========================= */ function validatePassword() { const pw = document.getElementById('user_password').value; const pw2 = document.getElementById('user_password_confirm').value; if (!PASSWORD_REGEX.test(pw)) { alert('비밀번호는 영문, 숫자, 특수기호를 포함한 8자 이상이어야 합니다.'); return false; } if (pw !== pw2) { alert('비밀번호가 일치하지 않습니다.'); return false; } return true; } /* ========================= 6. 가입하기 submit ========================= */ function initFormSubmit() { const form = document.forms.joinForm; form.addEventListener('submit', async (e) => { e.preventDefault(); if (!isIdChecked || checkedUserId !== form.userId.value.trim()) { alert('아이디 중복확인을 해주세요.'); return; } if (!REGEX.password.test(form.userPassword.value)) { alert('비밀번호 규칙을 확인하세요.'); return; } if (form.userPassword.value !== form.userPasswordConfirm.value) { alert('비밀번호가 일치하지 않습니다.'); return; } if (!REGEX.name.test(form.userName.value.trim())) { alert('이름에 특수문자는 사용할 수 없습니다.'); return; } // if (!REGEX.phone.test(form.userPhone.value.trim())) { // alert('휴대전화번호 형식이 올바르지 않습니다.'); // return; // } // ✅ 서버 전송 const formData = new FormData(form); const email = formData.get('userEmail') + '@' + (formData.get('emailDomain') === 'type' ? formData.get('customDomain') : formData.get('emailDomain')); const payload = { action: 'signup', memberType: formData.get('memberType'), userId: formData.get('userId'), password: formData.get('userPassword'), userName: formData.get('userName'), email, phone: formData.get('userPhone'), company: formData.get('companyName') || null, department: formData.get('departmentName') || null }; const res = await fetch('/kngil/bbs/join.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const data = await res.json(); if (data.success) { form.style.display = 'none'; document.querySelector('.messages').style.display = 'block'; } else { alert(data.message || '회원가입 실패'); } }); } /* ========================= 회원 가입 유효성 체크 ========================= */ function initPasswordValidation() { const pw = document.getElementById('user_password'); const pw2 = document.getElementById('user_password_confirm'); const msg = document.getElementById('password_help'); function validate() { if (!pw.value) { msg.textContent = '영문+숫자+특수기호 8자 이상'; msg.className = 'info-msg'; return; } if (!REGEX.password.test(pw.value)) { msg.textContent = '비밀번호 규칙을 만족하지 않습니다.'; msg.className = 'info-msg error'; return; } if (pw2.value && pw.value !== pw2.value) { msg.textContent = '비밀번호가 일치하지 않습니다.'; msg.className = 'info-msg error'; return; } msg.textContent = '사용 가능한 비밀번호입니다.'; msg.className = 'info-msg success'; } pw.addEventListener('input', validate); pw2.addEventListener('input', validate); } function initPhoneFormat() { const phone = document.getElementById('user_phone'); phone.addEventListener('input', () => { let v = phone.value.replace(/\D/g, ''); if (v.length <= 3) phone.value = v; else if (v.length <= 7) phone.value = `${v.slice(0,3)}-${v.slice(3)}`; else phone.value = `${v.slice(0,3)}-${v.slice(3,7)}-${v.slice(7,11)}`; }); } // function initNameValidation() { // const nameInput = document.getElementById('user_name'); // if (!nameInput) return; // nameInput.addEventListener('input', () => { // nameInput.value = nameInput.value.replace(/[^가-힣a-zA-Z\s]/g, ''); // }); // }