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

458 lines
12 KiB
JavaScript

/**
* mypage.js
* 마이페이지 관련 모든 모달 흐름 관리
*/
/* =========================
공통 유틸
========================= */
function show(id) {
const el = document.getElementById(id)
if (el) el.style.display = 'block'
}
function hide(id) {
const el = document.getElementById(id)
if (el) el.style.display = 'none'
}
/* =========================
마이페이지 1단계 (비밀번호 인증)
- 헤더에서 호출
========================= */
window.mypage01 = function () {
if (!window.IS_LOGIN) {
if (typeof window.login === 'function') {
window.login()
}
return
}
show('pop_mypage01')
}
/* =========================
마이페이지 2단계 (실제 마이페이지)
========================= */
let currentPage = 1
window.mypage02 = async function (page = 1) {
currentPage = page
hide('pop_mypage01')
try {
const res = await fetch(`/kngil/bbs/mypage02.php?page=${page}`)
const json = await res.json()
if (json.status !== 'success') {
alert(json.message || '데이터 로드 실패')
return
}
renderMyPage02(json.user)
renderMyPageHistory(json.history)
renderPagination(json.pagination)
show('pop_mypage02')
} catch (e) {
console.error(e)
alert('마이페이지 로딩 오류')
}
}
function renderMyPage02(data) {
// 이름 / ID
document.getElementById('mp_user_nm').textContent = data.user_nm
document.getElementById('mp_user_id').textContent = `(${data.user_id})`
// 연락처
document.getElementById('mp_tel').textContent = data.tel_no || '-'
document.getElementById('mp_email').textContent = data.email || '-'
// 회사 정보
document.getElementById('mp_co_nm').textContent = data.co_nm || '-'
document.getElementById('mp_dept_nm').textContent = data.dept_nm || '-'
// 사용량
document.getElementById('mp_tot_use').textContent =
Number(data.tot_use || 0).toLocaleString()
document.getElementById('mp_year_use').textContent =
Number(data.year_use || 0).toLocaleString()
}
function formatDate(dateStr) {
if (!dateStr) return '-'
const d = new Date(dateStr)
const yy = String(d.getFullYear()).slice(2)
const mm = String(d.getMonth() + 1).padStart(2, '0')
const dd = String(d.getDate()).padStart(2, '0')
return `${yy}-${mm}-${dd}`
}
function renderMyPageHistory(list) {
const tbody = document.getElementById('mp_history_body')
tbody.innerHTML = ''
if (!list.length) {
tbody.innerHTML = `
<tr>
<td colspan="4" style="text-align:center;">사용 이력이 없습니다.</td>
</tr>
`
return
}
list.forEach((row, idx) => {
const tr = document.createElement('tr')
tr.innerHTML = `
<td>${(currentPage - 1) * 5 + idx + 1}</td>
<td class="tit">${row.ser_bc}</td>
<td>${formatDate(row.use_dt)}</td>
<td><em>${Number(row.use_area).toLocaleString()}</em></td>
`
tbody.appendChild(tr)
})
}
function renderPagination(p) {
const ul = document.querySelector('.pagination-list')
if (!ul) return
ul.innerHTML = ''
for (let i = 1; i <= p.totalPages; i++) {
const li = document.createElement('li')
li.className = (i === p.page) ? 'on' : ''
const a = document.createElement('a')
a.href = '#'
a.textContent = i
a.addEventListener('click', (e) => {
e.preventDefault()
mypage02(i)
})
li.appendChild(a)
ul.appendChild(li)
}
}
/* =========================
마이페이지 3단계 (마이페이지 정보수정)
========================= */
window.mypage03 = async function () {
// ✅ 비밀번호 변경 영역 초기 상태 강제
const rowCurrent = document.getElementById('row-pw-current')
const rowNew = document.getElementById('row-pw-new')
const rowView = document.querySelector('.btn-sm.change')?.closest('tr')
rowCurrent && (rowCurrent.style.display = 'none')
rowNew && (rowNew.style.display = 'none')
rowView && (rowView.style.display = '')
try {
const res = await fetch('/kngil/bbs/mypage03.php')
const json = await res.json()
if (json.status !== 'success') {
alert(json.message)
return
}
fillMyPage03(json.data)
bindPasswordValidation()
hide('pop_mypage02')
show('pop_mypage03')
bindPasswordChangeUI()
} catch (e) {
console.error(e)
alert('회원정보 조회 오류')
}
};
;(function bindMyPage03Save() {
const popup = document.getElementById('pop_mypage03')
if (!popup) return
const btnSave = popup.querySelector('.btn-full')
btnSave.addEventListener('click', async () => {
const password = popup.querySelector('#new_pw')?.value.trim() || ''
const emailId = popup.querySelector('.e-id')?.value.trim()
const domainSel = popup.querySelector('#domain_list')
const customDomain = popup.querySelector('#custom_domain')
let email = ''
if (emailId) {
const domain =
domainSel.value === 'type'
? customDomain.value.trim()
: domainSel.options[domainSel.selectedIndex].text
email = `${emailId}@${domain}`
}
const telNo = popup.querySelector('#user_phone')?.value.trim()
const deptNm = popup.querySelector('#department_name')?.value.trim()
try {
const res = await fetch('/kngil/bbs/mypage03.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
password,
email,
tel_no: telNo,
dept_nm: deptNm
})
})
const json = await res.json()
if (json.status === 'success') {
alert('정보가 수정되었습니다.')
hide('pop_mypage03')
mypage02()
} else {
alert(json.message)
}
} catch (e) {
console.error(e)
alert('저장 중 오류 발생')
}
})
})();
function fillMyPage03(data) {
const popup = document.getElementById('pop_mypage03')
if (!popup) return
/* =========================
아이디
========================= */
const idInput = popup.querySelector('input[readonly]')
if (idInput) idInput.value = data.user_id || ''
/* =========================
이름
========================= */
const nameInput = popup.querySelector('input[placeholder="이지빔"]')
if (nameInput) nameInput.value = data.user_nm || ''
/* =========================
이메일
========================= */
if (data.email) {
const [emailId, domain] = data.email.split('@')
const emailInput = popup.querySelector('.e-id')
const domainList = popup.querySelector('#domain_list')
const customDomain = popup.querySelector('#custom_domain')
if (emailInput) emailInput.value = emailId
// 도메인 목록에 있으면 선택
const option = [...domainList.options].find(opt => opt.text === domain)
if (option) {
domainList.value = option.value
customDomain.classList.add('d-none')
customDomain.value = ''
} else {
domainList.value = 'type'
customDomain.classList.remove('d-none')
customDomain.value = domain
}
}
/* =========================
부서명
========================= */
const deptInput = popup.querySelector('#department_name')
if (deptInput) deptInput.value = data.dept_nm || ''
/* =========================
휴대폰 (표시만)
========================= */
const phoneInput = popup.querySelector('#user_phone')
if (phoneInput) phoneInput.value = data.tel_no || ''
}
/* =========================
비밀번호 재인증 처리
========================= */
;(function bindPasswordVerify() {
const popup = document.getElementById('pop_mypage01')
if (!popup) return
const form = popup.querySelector('.tab-content.id form')
if (!form) return
form.addEventListener('submit', async (e) => {
e.preventDefault()
const pwInput = popup.querySelector('#login_password')
const pw = pwInput?.value.trim()
if (!pw) {
alert('비밀번호를 입력하세요.')
pwInput?.focus()
return
}
try {
const res = await fetch('/kngil/bbs/mypage01.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ pw })
})
const json = await res.json()
if (json.status === 'success') {
pwInput.value = ''
window.mypage02()
} else {
alert(json.message || '비밀번호가 올바르지 않습니다.')
pwInput.focus()
}
} catch (err) {
console.error('[mypage verify error]', err)
alert('인증 중 오류가 발생했습니다.')
}
})
})(); // ✅ IIFE 종료
/* =========================
공통 닫기
========================= */
window.closeMyPage = function () {
hide('pop_mypage01')
hide('pop_mypage02')
hide('pop_mypage03')
}
/* =========================
새로고침 / bfcache 대응 (script-only)
========================= */
window.addEventListener('pageshow', () => {
['pop_mypage01','pop_mypage02','pop_mypage03']
.forEach(hide)
})
/* =========================
비밀번호 변경 UI 토글
========================= */
function bindPasswordChangeUI() {
const rowOriginal = document.getElementById('row-pw-original')
const rowNew = document.getElementById('row-pw-new')
const btnChange = document.getElementById('btnPwChange')
const btnCancel = document.getElementById('btnPwCancel')
if (!rowOriginal || !rowNew || !btnChange || !btnCancel) {
console.warn('[mypage] password toggle elements missing')
return
}
// 초기 상태
rowNew.style.display = 'none'
// 비밀번호 변경
btnChange.addEventListener('click', () => {
rowOriginal.style.display = 'none'
rowNew.style.display = ''
})
// 취소
btnCancel.addEventListener('click', () => {
rowOriginal.style.display = ''
rowNew.style.display = 'none'
document.getElementById('current_pw').value = ''
document.getElementById('new_pw').value = ''
document.getElementById('new_pw_confirm').value = ''
})
}
/* =========================
회원정보 유효성 체크
========================= */
function bindPasswordValidation() {
const pw = document.getElementById('new_pw')
const pwConfirm = document.getElementById('new_pw_confirm')
const msg = document.getElementById('pwPolicyMsg')
if (!pw || !pwConfirm || !msg) return
function updateMessage(text, isError = true) {
msg.textContent = text
msg.classList.remove('d-none')
msg.style.color = isError ? '#e60000' : '#2e7d32'
}
function validate() {
const v = pw.value
const c = pwConfirm.value
if (!v && !c) {
msg.classList.add('d-none')
return
}
const policy = checkPasswordPolicy(v)
if (!policy.length) {
updateMessage('비밀번호는 8자 이상이어야 합니다.')
return
}
if (!policy.eng) {
updateMessage('영문자를 포함해야 합니다.')
return
}
if (!policy.num) {
updateMessage('숫자를 포함해야 합니다.')
return
}
if (!policy.special) {
updateMessage('특수문자를 포함해야 합니다.')
return
}
if (c && v !== c) {
updateMessage('비밀번호가 일치하지 않습니다.')
return
}
updateMessage('사용 가능한 비밀번호입니다.', false)
}
pw.addEventListener('input', validate)
pwConfirm.addEventListener('input', validate)
}
function checkPasswordPolicy(pw) {
return {
length: pw.length >= 8,
eng: /[a-zA-Z]/.test(pw),
num: /[0-9]/.test(pw),
special: /[^a-zA-Z0-9]/.test(pw)
}
}