Files
kngil_home/kngil/js/join.js
2026-01-30 17:20:52 +09:00

308 lines
8.1 KiB
JavaScript

/* =========================
전역 상태값
========================= */
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, '');
// });
// }