최초 커밋
This commit is contained in:
@@ -0,0 +1,452 @@
|
||||
<?php
|
||||
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
|
||||
include_once('./_common.php');
|
||||
|
||||
$member = array_merge(array(
|
||||
'mb_id' => '',
|
||||
'mb_name' => '',
|
||||
'mb_hp' => '',
|
||||
'mb_comp' => '',
|
||||
'mb_comp_team' => '',
|
||||
), is_array($member) ? $member : array());
|
||||
|
||||
//add_stylesheet('<link rel="stylesheet" href="'.$member_skin_url.'/style.css">', 0);
|
||||
?>
|
||||
|
||||
<!--popup_wrap-->
|
||||
<div class="popup_wrap" id="pop_mypage03">
|
||||
<!--popup_in-->
|
||||
<div class="popup_in">
|
||||
<button class="btn_close">
|
||||
<div class="close_div"><img src="<?php echo G5_URL ?>/img/ico_close.svg" alt=""></div>
|
||||
</button>
|
||||
<!--popup_content-->
|
||||
<div class="popup_container mypage edit">
|
||||
<!--pop_join_left-->
|
||||
<div class="popup_tit">
|
||||
<h1 class="h_1">My Page</h1>
|
||||
<!-- <h3 class="h_3">
|
||||
소중한 <em>내 정보</em>를 <br>
|
||||
<em>최신</em>으로 관리하세요.
|
||||
</h3> -->
|
||||
</div>
|
||||
<!--//pop_join_right-->
|
||||
<div class="popup_contents_wrap">
|
||||
<fieldset>
|
||||
<!--tbl_wrap-->
|
||||
<div id="register_form" class="tbl_wrap" style="height: 400px;">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="h_4">ID</th>
|
||||
<td>
|
||||
<div class="id_wrap">
|
||||
<input type="text" class="full_input" id="show_mb_id" name="mb_id" value="<?php echo $member['mb_id'] ?>" readonly style="color: #9aa0a6;">
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="h_4">Employee ID</th>
|
||||
<td>
|
||||
<div class="password_wrap">
|
||||
<input type="text" name="mb_password" id="show_mb_employeeid" class="frm_input full_input" data-editable>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="h_4">Name</th>
|
||||
<td>
|
||||
<div class="name_wrap">
|
||||
<input type="text" id="show_mb_name" name="mb_name" value="<?php echo get_text($member['mb_name']) ?>" class="frm_input full_input" data-editable>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="h_4">Position</th>
|
||||
<td>
|
||||
<div class="position_wrap">
|
||||
<input type="text" id="show_mb_position" name="mb_position" class="frm_input full_input" data-editable>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="h_4">Mobile</th>
|
||||
<td>
|
||||
<div class="phone_wrap">
|
||||
<input type="text" name="mb_hp" value="<?php echo preg_replace("/[^0-9]*/s", "", $member['mb_hp']); ?>" id="show_mb_hp" class="frm_input full_input" data-editable>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row_company">
|
||||
<th class="h_4">Company</th>
|
||||
<td>
|
||||
<div class="company_wrap">
|
||||
<input type="text" name="mb_comp" value="<?php echo get_text($member['mb_comp'])?>" id="show_mb_comp" class="frm_input" data-editable>
|
||||
<input type="text" name="mb_comp_team" value="<?php echo get_text($member['mb_comp_team'])?>" id="show_mb_comp_team" class="frm_input" data-editable>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="row_team_external" style="display:none;">
|
||||
<th class="h_4">Department</th>
|
||||
<td>
|
||||
<div class="team_wrap">
|
||||
<input type="text" name="mb_comp_team_ext" id="show_mb_comp_team_ext" class="frm_input" data-editable placeholder="소속부서">
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="btn_confirm">
|
||||
<!-- <button type="button" onclick="mypage02();" class="btn_cancel">취소</button> -->
|
||||
<button type="button" id="btn_profile_edit" class="btn_submit" >Save</button>
|
||||
</div>
|
||||
<div class="sign_out">
|
||||
<a href="#" id="btn_delete_account"><i class="signout"></i>Delete account</a>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
<!--//pop_join_right-->
|
||||
</div>
|
||||
<!--//popup_content-->
|
||||
</div>
|
||||
<!--//popup_in-->
|
||||
</div>
|
||||
<!--//popup_wrap-->
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
// === 설정 ===
|
||||
const INTERNAL_DOMAINS = [
|
||||
"hanmaceng.co.kr","samaneng.com","jangheon.co.kr",
|
||||
"hallasanup.com","pre-cast.co.kr","baroncs.co.kr"
|
||||
];
|
||||
const MAX_LOGINID_RETRY = 5;
|
||||
|
||||
// === 상태 ===
|
||||
let loginIdRetryCount = 0;
|
||||
|
||||
// === 엘리먼트 캐시 ===
|
||||
const $btn = $('#pop_mypage03 #btn_profile_edit');
|
||||
const $edit = $('[data-editable]');
|
||||
|
||||
const $id = $('#show_mb_id'); // 아이디(=이메일, readonly)
|
||||
const $empId = $('#show_mb_employeeid'); // 사번(내부)
|
||||
const $name = $('#show_mb_name'); // 이름
|
||||
const $pos = $('#show_mb_position'); // 직위(내부)
|
||||
const $phone = $('#show_mb_hp'); // 휴대전화
|
||||
const $comp = $('#show_mb_comp'); // 내부=가족사, 외부=회사명
|
||||
const $team = $('#show_mb_comp_team'); // 소속부서(내/외 공통)
|
||||
|
||||
const $rowEmp = $empId.closest('tr');
|
||||
const $rowPos = $pos.closest('tr');
|
||||
const $rowCompany = $('#row_company'); // 회사정보 행
|
||||
|
||||
// === 전화번호 포맷/검증 ===
|
||||
function autoHyphen010(inputEl) {
|
||||
let v = inputEl.value.replace(/\D/g, '').slice(0, 11); // 숫자만 11자리까지
|
||||
if (v.length < 4) { inputEl.value = v; return; }
|
||||
if (!v.startsWith('010')) { inputEl.value = v; return; }
|
||||
if (v.length <= 7) {
|
||||
inputEl.value = v.slice(0,3) + '-' + v.slice(3);
|
||||
} else {
|
||||
inputEl.value = v.slice(0,3) + '-' + v.slice(3,7) + '-' + v.slice(7);
|
||||
}
|
||||
}
|
||||
function isValidPhone010(str) {
|
||||
return /^010-\d{4}-\d{4}$/.test((str||'').trim());
|
||||
}
|
||||
|
||||
// === 유틸 ===
|
||||
function isInternal(email) {
|
||||
if (!email) return false;
|
||||
const domain = (email.split('@')[1] || '').toLowerCase();
|
||||
return INTERNAL_DOMAINS.includes(domain);
|
||||
}
|
||||
function getEmailFromUI() {
|
||||
return ($id.val() || sessionStorage.getItem('loginId') || '').trim();
|
||||
}
|
||||
function showHint($input, msg) {
|
||||
clearHint($input);
|
||||
$input.addClass('input-error').after('<span class="field-hint">'+msg+'</span>');
|
||||
}
|
||||
function clearHint($input) {
|
||||
$input.removeClass('input-error').siblings('.field-hint').remove();
|
||||
}
|
||||
function clearAllHints() {
|
||||
$edit.each(function(){ clearHint($(this)); });
|
||||
}
|
||||
|
||||
// === 내부/외부 UI 토글 ===
|
||||
function applyTenantUI(email) {
|
||||
const internal = isInternal(email);
|
||||
|
||||
if (internal) {
|
||||
$rowEmp.show();
|
||||
$rowPos.show();
|
||||
$rowCompany.show();
|
||||
$comp.attr('placeholder','가족사');
|
||||
$team.attr('placeholder','소속부서');
|
||||
} else {
|
||||
$rowEmp.hide().find('input').val('');
|
||||
$rowPos.hide().find('input').val('');
|
||||
$rowCompany.show(); // 회사정보는 유지
|
||||
$comp.attr('placeholder','회사명');
|
||||
$team.attr('placeholder','소속부서');
|
||||
}
|
||||
}
|
||||
|
||||
// === 검증 ===
|
||||
function validate() {
|
||||
clearAllHints();
|
||||
const name = ($name.val() || '').trim();
|
||||
const phone = ($phone.val() || '').trim();
|
||||
const email = getEmailFromUI();
|
||||
const internal = isInternal(email);
|
||||
|
||||
let ok = true;
|
||||
if (!name) showHint($name, '이름을 입력해 주세요.'), ok = false;
|
||||
if (!/^[0-9\-]{9,15}$/.test(phone)) showHint($phone, '숫자(하이픈 가능) 9~15자리로 입력해 주세요.'), ok = false;
|
||||
|
||||
if (internal) {
|
||||
if (!($pos.val() || '').trim()) showHint($pos, '직위를 입력해 주세요.'), ok = false;
|
||||
if (!($comp.val() || '').trim()) showHint($comp, '가족사를 입력해 주세요.'), ok = false;
|
||||
if (!($team.val() || '').trim()) showHint($team, '소속부서를 입력해 주세요.'), ok = false;
|
||||
if (!($empId.val()|| '').trim()) showHint($empId,'사번을 입력해 주세요.'), ok = false;
|
||||
} else {
|
||||
if (!($comp.val() || '').trim()) showHint($comp, '회사명을 입력해 주세요.'), ok = false;
|
||||
if (!($team.val() || '').trim()) showHint($team, '소속부서를 입력해 주세요.'), ok = false;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// === 저장 ===
|
||||
function saveProfile() {
|
||||
if (!validate()) return;
|
||||
|
||||
// const refreshJwt = sessionStorage.getItem('refreshJwt') || '';
|
||||
// if (!refreshJwt) { alert('인증 정보가 만료되었습니다. 다시 로그인해 주세요.'); return; }
|
||||
|
||||
const email = getEmailFromUI();
|
||||
const internal = isInternal(email);
|
||||
|
||||
const payload = {
|
||||
email, // loginId
|
||||
name: ($name.val() || '').trim(),
|
||||
phone: ($phone.val() || '').trim(),
|
||||
position: ($pos.val() || '').trim(), // 외부여도 전송 무해
|
||||
completeForm: true
|
||||
};
|
||||
|
||||
if (internal) {
|
||||
payload.familyCompany = ($comp.val() || '').trim(); // 가족사
|
||||
payload.team = ($team.val() || '').trim(); // 소속부서
|
||||
payload.familyUniqueKey = ($empId.val() || '').trim(); // 사번
|
||||
payload.employeeId = payload.familyUniqueKey; // 호환 키
|
||||
} else {
|
||||
payload.company = ($comp.val() || '').trim(); // 회사명
|
||||
payload.team = ($team.val() || '').trim(); // 소속부서
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '/eng/skin/member/basic/descope_update.php',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: payload,
|
||||
beforeSend(){ $btn.prop('disabled', true).text('저장중…'); },
|
||||
complete(){ $btn.prop('disabled', false).text('Save'); },
|
||||
success(res){
|
||||
if (res.status === 'ok') {
|
||||
alert('정보가 저장되었습니다.');
|
||||
closeMyPagePopup(); // ✅ 저장 성공 시 팝업 닫기
|
||||
// 필요 시 전체 새고: location.reload();
|
||||
} else {
|
||||
alert(res.message || '저장에 실패했습니다.');
|
||||
}
|
||||
},
|
||||
error(xhr){
|
||||
alert('서버 오류: ' + (xhr.statusText||'') + '\n' + (xhr.responseText||''));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// === 팝업 닫기 ===
|
||||
function closeMyPagePopup() {
|
||||
// 닫기 버튼이 자체 로직을 가지고 있으면 그걸 트리거하는 게 가장 안전
|
||||
const $closeBtn = $('#pop_mypage03 .btn_close');
|
||||
if ($closeBtn.length) {
|
||||
$closeBtn.trigger('click');
|
||||
} else {
|
||||
// 폴백: 직접 숨김 처리
|
||||
$('#pop_mypage03').hide();
|
||||
$('body').css('overflow','');
|
||||
}
|
||||
}
|
||||
|
||||
// === 이벤트 바인딩 ===
|
||||
// 입력칸 항상 편집 가능 + 버튼은 항상 "저장"
|
||||
$edit.prop('readonly', false);
|
||||
$btn.text('Save');
|
||||
|
||||
// 전화번호 입력 바인딩(중복 방지)
|
||||
$phone.off('.hp');
|
||||
let hpWarnedOnce = false;
|
||||
$phone
|
||||
.on('input.hp', function () {
|
||||
autoHyphen010(this);
|
||||
hpWarnedOnce = false; // 다시 입력하면 경고 플래그 해제
|
||||
})
|
||||
.on('paste.hp', function () {
|
||||
const el = this;
|
||||
setTimeout(function(){ autoHyphen010(el); hpWarnedOnce = false; }, 0);
|
||||
})
|
||||
.on('blur.hp', function () {
|
||||
const v = $(this).val().trim();
|
||||
if (v && !isValidPhone010(v) && !hpWarnedOnce) {
|
||||
hpWarnedOnce = true;
|
||||
alert('휴대전화번호는 010-1234-5678 형식으로 입력해 주세요.');
|
||||
setTimeout(() => { $phone.focus(); }, 0); // 즉시 focus는 blur 루프 유발
|
||||
}
|
||||
});
|
||||
|
||||
// 버튼: 바로 저장
|
||||
$btn.off('click.mypage').on('click.mypage', function (e) {
|
||||
e.preventDefault();
|
||||
// 저장 직전 최종 포맷 체크 (한 번 더)
|
||||
if (!isValidPhone010(($phone.val()||'').trim())) {
|
||||
alert('휴대전화번호는 010-1234-5678 형식으로 입력해 주세요.');
|
||||
$phone.focus();
|
||||
return;
|
||||
}
|
||||
saveProfile(); // ✅ 한 번 클릭으로 바로 저장
|
||||
});
|
||||
|
||||
// 탈퇴 버튼 클릭 → 삭제 함수 호출
|
||||
$(document).on('click', '#btn_delete_account', function(e){
|
||||
e.preventDefault();
|
||||
deleteDescopeUser();
|
||||
});
|
||||
|
||||
// === customAttributes 안전 접근 ===
|
||||
function ca(u, keys) {
|
||||
for (const k of keys) {
|
||||
const v = u && u.customAttributes && u.customAttributes[k];
|
||||
if (v !== undefined && v !== null && String(v).length) return v;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// === 사용자 조회 ===
|
||||
function loadDescopeUser() {
|
||||
const loginId = sessionStorage.getItem('loginId');
|
||||
if (!loginId) {
|
||||
if (loginIdRetryCount < MAX_LOGINID_RETRY) {
|
||||
loginIdRetryCount++;
|
||||
return setTimeout(loadDescopeUser, 150 * Math.pow(2, loginIdRetryCount - 1));
|
||||
}
|
||||
return;
|
||||
}
|
||||
loginIdRetryCount = 0;
|
||||
|
||||
$.ajax({
|
||||
url: '/eng/skin/member/basic/descope_user_search.php',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: { loginId },
|
||||
// timeout: 8000,
|
||||
success(res) {
|
||||
if (!(res.status === 'ok' && res.user)) { alert('사용자 정보를 불러올 수 없습니다.'); return; }
|
||||
const u = res.user;
|
||||
|
||||
const email = (u.loginIds && u.loginIds[0]) ? u.loginIds[0] : (u.email || loginId);
|
||||
$id.val(email);
|
||||
$name.val(u.name || '');
|
||||
$phone.val(u.phone || '');
|
||||
$pos.val(ca(u, ['position']) || '');
|
||||
|
||||
// 공통값
|
||||
$comp.val(ca(u, ['familyCompany','company']) || '');
|
||||
$team.val(ca(u, ['team']) || '');
|
||||
$empId.val(isInternal(email) ? (ca(u, ['familyUniqueKey','employeeId']) || '') : '');
|
||||
|
||||
// UI 분기
|
||||
applyTenantUI(email);
|
||||
|
||||
// 탈퇴용 ID 저장
|
||||
if (u.userId) sessionStorage.setItem('descopeUserId', u.userId);
|
||||
},
|
||||
error(xhr) {
|
||||
alert('서버 통신 오류: ' + (xhr.statusText || ''));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// === 외부에서 로그인 성공 시 호출됨 ===
|
||||
window.onLoginSuccess = function (loginId, sessionJwt, refreshJwt) {
|
||||
if (loginId) sessionStorage.setItem('loginId', loginId);
|
||||
if (sessionJwt) sessionStorage.setItem('sessionJwt', sessionJwt);
|
||||
if (refreshJwt) sessionStorage.setItem('refreshJwt', refreshJwt);
|
||||
loadDescopeUser();
|
||||
};
|
||||
|
||||
// === 팝업 표시될 때마다 갱신 ===
|
||||
const popupEl = document.getElementById('pop_mypage03');
|
||||
if (popupEl) {
|
||||
new MutationObserver((muts) => {
|
||||
muts.forEach((m) => {
|
||||
if (m.type === 'attributes' && (m.attributeName === 'style' || m.attributeName === 'class')) {
|
||||
const visible = $('#pop_mypage03').is(':visible') || $('#pop_mypage03').css('display') !== 'none';
|
||||
if (visible) {
|
||||
setTimeout(() => {
|
||||
loadDescopeUser();
|
||||
const email = getEmailFromUI();
|
||||
if (email) applyTenantUI(email);
|
||||
}, 50);
|
||||
}
|
||||
}
|
||||
});
|
||||
}).observe(popupEl, { attributes: true, attributeFilter: ['style','class'] });
|
||||
}
|
||||
|
||||
// === 최초 진입 ===
|
||||
document.addEventListener('DOMContentLoaded', loadDescopeUser);
|
||||
|
||||
// === 탈퇴 ===
|
||||
window.deleteDescopeUser = function () {
|
||||
// 폴백: sessionStorage → 입력칸
|
||||
const userId = sessionStorage.getItem('descopeUserId') || '';
|
||||
const uiLogin = ($('#show_mb_id').val() || '').trim();
|
||||
const loginId = sessionStorage.getItem('loginId') || uiLogin;
|
||||
|
||||
if (!userId && !loginId) return alert('대상 정보가 없습니다. 다시 로그인 후 시도해 주세요.');
|
||||
if (!confirm('Are you sure you want to delete your account? This action cannot be undone.')) return;
|
||||
|
||||
$.ajax({
|
||||
url: '/eng/skin/member/basic/descope_user_delete.php',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: { userId, loginId },
|
||||
success(res) {
|
||||
if (res.status === 'ok') {
|
||||
alert('Your account has been successfully deleted.');
|
||||
// 🔑 sessionStorage 완전 초기화
|
||||
sessionStorage.clear();
|
||||
localStorage.clear();
|
||||
location.reload();
|
||||
} else {
|
||||
alert('탈퇴 실패: ' + (res.message || '알 수 없는 오류'));
|
||||
}
|
||||
},
|
||||
error(xhr) {
|
||||
alert('서버 오류로 탈퇴 실패: ' + (xhr.statusText || ''));
|
||||
}
|
||||
});
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user