This commit is contained in:
Rinjae
2025-08-07 15:36:26 +09:00
commit cc925e0475
1172 changed files with 142573 additions and 0 deletions
@@ -0,0 +1,199 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/kbank_base_layout}">
<body>
<section layout:fragment="contentFragment" class="content">
<script th:src="@{/js/htmx.min.js}"></script>
<div class="content_wrap">
<div class="sub_title2">
<h2 class="title add" th:if="${!isInvited}">개인회원가입</h2>
<h2 class="title add" th:if="${isInvited}">법인회원가입</h2>
</div>
<div class="inner i_cs h_inner2">
<div class="top_info" th:if="${!isInvited}">
<ul>
<li>서비스 또는 API 사용을 원하실 경우 법인회원 승인 후 이용하실 수 있습니다.</li>
</ul>
</div>
<!-- 약관동의 섹션 -->
<input type="hidden" id="csrf" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
<th:block th:replace="~{apps/register/userAgreementContent :: agreementContent(${termsOfUse}, ${privacyCollect})}"></th:block>
<!-- 기본 정보 입력 섹션 -->
<form name="portalUser" id="registerForm" role="form" th:action="@{/signup/portalUser}"
th:object="${portalUser}" method="post">
<!-- 법인 정보 섹션, 초대받은 경우에만 -->
<div class="terms_box" th:if="${isInvited}">
<p>법인 정보</p>
</div>
<div class="form_type" th:if="${isInvited}">
<div class="info1">
<p class="title w_tit">
<span>법인명</span>
</p>
<div class="info_line">
<div class="info_box1 w_inp4">
<input type="text" name="companyName" class="common_input_type_1"
th:classappend="${isInvited ? 'input-readonly' : ''}" th:value="${orgName}" readonly>
</div>
</div>
</div>
</div>
<!-- end 법인 정보 섹션, 초대받은 경우에만 -->
<div class="terms_box">
<p>기본 정보</p>
<span class="dot">필수 입력란입니다</span>
</div>
<div class="form_type" th:if="${registrationType == isInvited ? 'corporate' :'personal'}">
<th:block th:replace="~{apps/register/components/commonUserInfoForm :: commonUserInfo}"></th:block>
<th:block th:replace="~{apps/register/components/newUserInfoForm :: newUserForm}"></th:block>
</div>
<div class="form_type">
<div class="btn_application">
<a type="button" class="common_btn_type_1 gray" id="cancelButton"><span>취소</span></a>
<div class="btn_gap"></div>
<a type="button" class="common_btn_type_1 btn_register"><span>가입신청</span></a>
</div>
</div>
</form>
</div>
</div>
</section>
<th:block layout:fragment="contentScript">
<script th:if="${error}" th:inline="javascript">
$(document).ready(function () {
customPopups.showAlert([[${error}]]);
});
</script>
<script th:replace="~{apps/register/userAgreementContent :: agreementScript}"></script>
<script th:replace="~{apps/register/components/commonUserInfoForm :: commonUserInfoScript}"></script>
<script th:replace="~{apps/register/components/newUserInfoForm :: newUserScript}"></script>
<script>
let form = document.getElementById('registerForm');
let agreementForm = document.getElementById('agreementForm');
let btn_register = document.querySelector('.btn_register');
let isAuthVerified = false;
// 인증 완료 이벤트 리스너
document.addEventListener('authVerified', function() {
isAuthVerified = true;
});
// 이메일 유효성 검사 함수
function isValidEmail(email) {
const safeEmailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
return safeEmailRegex.test(email);
}
// 폼 유효성 검사 함수
function checkFormValidity() {
return isValidEmail($('#loginId').val()) &&
($('#password').val() === $('#password2').val()) &&
($('#userName').val().trim() !== '') &&
$('#termsOfUse').prop('checked') &&
$('#privacyCollect').prop('checked') &&
(combineMobileNumber('#mobileNumber') !== null) &&
isAuthVerified; // 인증 여부 확인
}
let isSubmitting = false;
// 등록 버튼 클릭 이벤트
btn_register.addEventListener('click', function(event) {
event.preventDefault();
event.stopPropagation();
// Prevent resubmission
if (isSubmitting) {
console.log('Form is already being submitted...');
return;
}
isSubmitting = true;
btn_register.disabled = true;
form.classList.add('was-validated');
agreementForm.classList.add('was-validated');
if (checkFormValidity() && form.checkValidity() && agreementForm.checkValidity()) {
// 약관 동의 폼의 데이터를 hidden input으로 추가
let agreementFormData = new FormData(agreementForm);
for (let pair of agreementFormData.entries()) {
if (!form.querySelector('input[name="' + pair[0] + '"]')) {
let input = document.createElement('input');
input.type = 'hidden';
input.name = pair[0];
input.value = pair[1];
form.appendChild(input);
}
}
// 불필요한 hidden input 제거
const unnecessaryFields = ['isPasswordValid', 'isPasswordMatch'];
unnecessaryFields.forEach(fieldName => {
const field = form.querySelector(`input[name="${fieldName}"]`);
if (field) {
field.remove();
}
});
// authCompletedYn 값 설정
const authCompletedField = document.createElement('input');
authCompletedField.type = 'hidden';
authCompletedField.name = 'authCompletedYn';
authCompletedField.value = isAuthVerified ? 'Y' : 'N';
form.appendChild(authCompletedField);
form.submit();
} else {
customPopups.showAlert('모든 필수 항목을 입력하고 약관에 동의해주세요.');
isSubmitting = false;
btn_register.disabled = false;
}
});
// 취소버튼 클릭시
document.getElementById('cancelButton').addEventListener('click', function() {
location.href = '/login';
});
// HTMX 이벤트 리스너 - 모든 HTMX 응답을 중앙에서 처리
document.body.addEventListener('htmx:afterRequest', function(event) {
const targetId = event.detail.target.id;
let response;
try {
response = JSON.parse(event.detail.xhr.response);
} catch (e) {
console.error('응답 JSON 파싱 실패:', e);
customPopups.showAlert('서버 응답을 처리할 수 없습니다.');
return;
}
// 커스텀 헤더를 체크하여 등록 검증 요청 처리
if (event.detail.xhr.getResponseHeader('X-Custom-Handler') === 'registration-validation') {
if (response && response.message) {
if (response.status === 'SUCCESS') {
customPopups.showSuccess(response.message);
} else {
customPopups.showAlert(response.message);
}
}
return;
}
// 응답 처리 로직
if (targetId === 'email-validation') {
// commonUserInfoForm의 함수 호출
handleEmailValidationResponse(response);
} else if (targetId === 'password-validation' || targetId === 'password-match-validation') {
// 비밀번호 검증은 컴포넌트에서 처리하도록 함
return;
}
});
</script>
</th:block>
</body>
</html>