초기소스

This commit is contained in:
jazz
2025-10-29 17:08:05 +09:00
parent e531aa9540
commit 439a379a02
7551 changed files with 1234427 additions and 3 deletions

View File

@@ -0,0 +1,895 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.w3.org/1999/html">
<head>
<!-- 메타정보 -->
<meta charset="UTF-8">
<!-- M자형 디스플레이 위해 "viewport-fit=cover" 속성 필요 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, viewport-fit=cover">
<meta name="description" th:content="${shopInfo.metaDc}">
<meta name="keywords" th:content="${shopInfo.metaKwrd}">
<!-- CSS -->
<!-- 공통 CSS-->
<link rel="stylesheet" href="/sopmall/mobile/css/default.css">
<!-- 테마 CSS-->
<link rel = 'stylesheet' th:href="|/sopmall/mobile${shopInfo.cssCours}|" th:if="${#strings.startsWith(shopInfo.cssCours, '/')}">
<link rel = 'stylesheet' th:href="|/sopmall/mobile/${shopInfo.cssCours}|" th:if="${!#strings.startsWith(shopInfo.cssCours, '/')}">
<!-- 파비콘-->
<link rel="icon" th:href="|/sopmall${shopInfo.fviconCours}|" th:if="${#strings.startsWith(shopInfo.fviconCours, '/')}">
<link rel="icon" th:href="|/sopmall/${shopInfo.fviconCours}|" th:if="${!#strings.startsWith(shopInfo.fviconCours, '/')}">
<!-- 타이틀-->
<title th:text="${shopInfo.metaSj}"></title>
<!-- jquery -->
<script src="/sopmall/mobile/vendor/jquery-3.7.1.min.js"></script>
<!--js-->
<!-- micromodal -->
<!-- https://github.com/Ghosh/micromodal -->
<script src="/sopmall/mobile/vendor/micromodal/micromodal.min.js"></script>
<!-- popModal -->
<link rel="stylesheet" type="text/css" href="/sopmall/mobile/vendor/popModal/popModal.min.css">
<script src="/sopmall/mobile/vendor/popModal/popModal.min.js"></script>
<style>
/* 기본적으로 모든 .boxTab__content 요소는 숨김 처리 */
.boxTab__content {
display: none;
}
/* current 클래스가 있는 경우에만 표시 */
.boxTab__content.current {
display: block;
}
</style>
</head>
<script>
$(document).ready(function(){
////햄버거 메뉴 관련 스크립트
// 좌측 메뉴 클릭시 해당 메뉴 보여주기
$('.fullMenu__menu__btn').on('click', function () {
$(this).addClass('current');
$(this).closest('li').siblings().find('.fullMenu__menu__btn').removeClass('current');
var index = $(this).closest('li').index() - 1; // 전체 메뉴 버튼을 뺀 나머지 버튼의 인덱스
$(this).closest('.fullMenu__content').find('.fullMenu__itemSection').eq(index).siblings().hide();
$(this).closest('.fullMenu__content').find('.fullMenu__itemSection').eq(index).show();
});
// 전체 메뉴 클릭시 전체 메뉴 보여주기
$('.fullMenuAll').on('click', function () {
$(this).addClass('current');
$(this).closest('li').siblings().find('.fullMenu__menu__btn').removeClass('current');
$(this).closest('.fullMenu__content').find('.fullMenu__itemSection').show();
});
//
$('.hamburgerTabBtn').on('click', function () {
$('.hamburgerTabBtn').removeClass('active');
$(this).addClass('active');
var index = $(this).closest('li').index();
$('.fullMenu__content').removeClass('active');
$('.fullMenu__content').eq(index).addClass('active');
});
MicroModal.init({
disableScroll: true,
awaitCloseAnimation: true,
});
});
/* ************************************************************
* 모바일 모달 show 함수
* modalId : 콜백 함수 이름
************************************************************* */
const openModal = (modalId) => {
MicroModal.show(modalId, {
onShow: function (modal) {
// 이미 존재하지 않는 경우에만 Hash 추가
if (window.location.hash !== '#' + modalId) {
window.history.pushState({modal: 'open'}, '', '#' + modalId);
}
}
});
if(modalId === 'hamburger-menu'){
window.history.replaceState({}, '', window.location.href.split('#')[0]);
}
}
/* ************************************************************
* 모바일 모달 닫고, URL Hash 제거
* modalId : 콜백 함수 이름
************************************************************* */
const closeModal = (modalId) => {
// 모달 닫힐 때 body 스크롤 복원
document.body.style.overflow = '';
// MicroModal을 사용해 모달 닫기
MicroModal.close(modalId);
// 추가적인 히스토리 항목을 생성하지 않고 URL에서 #이후부터 Hash 제거
window.history.replaceState({}, '', window.location.href.split('#')[0]);
}
/**************************************************************
* input
* 특정 input(select)에 특정 event 발생시 처리할 함수 지정
* 파라미터 설명{
* selector : 대상 input Object selector
* eventType : 대상 event종류(예시>keyup)
* callback : 대상 event발생 시 호출될 callback함수
* }
****************************************************************/
const fn_set_event = function (selector, eventType, callback) {
document.querySelector(selector).addEventListener(eventType, function () {
let target = this;
callback(target);
});
}
/**************************************************************
* 데이터 NULL 여부
* 파라미터 설명 {
* data : 데이터
* }
****************************************************************/
const fn_is_empty = (data) => {
if (typeof data === 'undefined' ||
data === 'undefined' ||
data === null ||
data === '' ||
data === 'null' ||
data.length === 0 ||
(typeof data === 'object' && !Object.keys(data).length)) {
return true;
} else {
return false;
}
}
/**************************************************************
* 포매팅 (input 값 포매팅)
* 전화번호(일반전화번호, 휴대전화번호, 대표번호) 자동 포매팅(-) 설정
* 파라미터 설명{
* target : 대상 Object
* }
****************************************************************/
const fn_fmt_telno = function (target) {
// 숫자만 허용
target.value = target.value.replace(/[^0-9]/g, '');
if (target.value.length <= 11) {
if (target.value.length == 11) {
// 휴대전화번호 혹은 02를 제외한 전화번호
target.value = target.value.replace(/(\d{3})(\d{4})(\d{4})/, '$1-$2-$3');
} else if (target.value.length == 9) {
// 02를 포함한 9자리 전화번호(02-000-0000)
target.value = target.value.replace(/(\d{2})(\d{3})(\d{4})/, '$1-$2-$3');
} else if (target.value.length == 8) {
// 대표전화번호 일 경우(0000-0000)
target.value = target.value.replace(/(\d{4})(\d{4})/, '$1-$2');
} else {
if (target.value.indexOf('02') == 0) {
// 02를 포함한 10자리 전화번호(02-0000-0000)
target.value = target.value.replace(/(\d{2})(\d{4})(\d{4})/, '$1-$2-$3');
} else {
// 02를 제외한 10자리 전화번호(032-000-0000)
target.value = target.value.replace(/(\d{3})(\d{3})(\d{4})/, '$1-$2-$3');
}
}
}
}
/* ********************************************************
* 주문 상세 이동
******************************************************** */
const fn_go_ordr_dtl = function () {
var accessUrl = document.getElementById('accessUrl').value;
if(accessUrl.startsWith("http://") && !(accessUrl.includes("dev.") || accessUrl.includes("loc."))){
accessUrl = accessUrl.replace("http://", "https://");
}
var form = document.getElementById('condForm');
form.setAttribute('method', 'post');
form.setAttribute('action', accessUrl+'/sopmal/main/selectNMbrOrdrDtlInqire');
form.submit();
}
/* ********************************************************
* 주문 번호 조회
******************************************************** */
const fn_select_oderNumbber = function() {
let sopMalCd = document.getElementById('sopMalCd').value;
let ordrInnb = document.getElementById('ordrInnb').value;
let mbtlnb = document.getElementById('mbtlnb').value;
let accessUrl = document.getElementById('accessUrl').value;
let mbtlnbEle = document.getElementById('mbtlnb');
if (fn_is_empty(ordrInnb)) {
alert("주문번호를 입력해주세요.");
return false;
}
if (fn_is_empty(mbtlnb)) {
alert("주문 시 입력한 휴대폰번호를 입력해주세요.");
return false;
}
// let params = {
// 'sopMalCd': sopMalCd,
// 'ordrInnb': ordrInnb,
// 'mbtlnb': mbtlnb
// };
const form = document.getElementById('condForm');
const formData = new FormData(form); // 폼 데이터
// fetch('/sopmal/main/selectNMbrMbtlnbInqire', {
fetch('/login/selectNMbrMbtlnbInqire', {
method: 'POST',
// body: formData
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
sopMalCd: sopMalCd,
ordrInnb: ordrInnb,
mbtlnb: mbtlnb,
accessUrl: accessUrl
})
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// let result = data.resBody;
// let parsedResult = JSON.parse(result.result);
// let confirmAt = parsedResult.confirmAt;
let confirmAt = data.confirmAt;
if (confirmAt === 'Y') {
fn_go_ordr_dtl();
} else {
alert("휴대폰번호가 일치하지않습니다.");
mbtlnbEle.focus();
}
})
.catch(error => {
alert("비회원 주문조회 실패");
console.error('Error:', error);
});
}
/* ********************************************************
* 체크박스 값변경
******************************************************** */
const fn_set_checkbox = function(_target) {
if ($(_target).is(':checked')) {
$(_target).val('Y');
} else {
$(_target).val('N');
}
}
/* ********************************************************
* 아이디 저장 기능 구현
******************************************************** */
document.addEventListener('DOMContentLoaded', function () {
const usernameInput = document.getElementById('username');
const rememberCheckbox = document.querySelector('input[type="checkbox"]');
const savedUsername = localStorage.getItem('savedUsername');
// 페이지 로드 시, 저장된 아이디가 있으면 입력 필드에 채워넣기
if (savedUsername) {
usernameInput.value = savedUsername;
rememberCheckbox.checked = true; // 체크박스도 체크 상태로 유지
}
// 체크박스 상태 변경 시 아이디 저장 또는 삭제
rememberCheckbox.addEventListener('change', function () {
if (this.checked) {
// 체크된 경우, 아이디를 localStorage에 저장
const username = usernameInput.value;
if (username) {
localStorage.setItem('savedUsername', username);
}
} else {
// 체크 해제된 경우, 저장된 아이디 삭제
localStorage.removeItem('savedUsername');
}
});
// 로그인 버튼 클릭 시 아이디 저장 처리
document.querySelector('.login__loginBtn').addEventListener('click', function () {
if (rememberCheckbox.checked) {
const username = usernameInput.value;
if (username) {
localStorage.setItem('savedUsername', username); // 아이디 저장
}
} else {
localStorage.removeItem('savedUsername'); // 체크 해제 시 아이디 삭제
}
});
});
document.addEventListener("DOMContentLoaded", function() {
// 서브 탭 메뉴 타입 2
var boxTabs = document.querySelectorAll(".boxTab__tabBtn");
var contents = document.querySelectorAll(".boxTab__content");
function resetBoxTabs() {
boxTabs.forEach(function(tab) {
tab.closest("li").classList.remove("active");
});
contents.forEach(function(content) {
content.classList.remove("current");
});
}
boxTabs.forEach(function(tab, index) {
tab.addEventListener("click", function() {
resetBoxTabs();
tab.closest("li").classList.add("active");
contents[index].classList.add("current");
});
});
// 상단 이동 스크롤 버튼
const scrollToTop = document.querySelector(".quick-menu__to-top > button");
scrollToTop.addEventListener('click', function () {
window.scrollTo({top: 0, behavior: 'smooth'});
});
// 2401016 햄버거 메뉴 수정
$('.menu_navigation_wrap .depth').click(function (e) {
e.preventDefault();
if ($(this).parent().hasClass('on')) {
$(this).parent().next().slideUp();
$(this).parent().removeClass('on');
return false;
}
$('.menu_navigation_wrap .depth').parent().removeClass('on');
$('.menu_navigation_wrap .view').slideUp();
$('.menu_navigation_wrap .view .subview').slideUp();
$('.menu_navigation_wrap .view .on').removeClass('on');
$(this).parent().next().slideToggle();
$(this).parent().toggleClass('on');
return false;
});
$('.menu_navigation_wrap .sublist .hasSub').click(function (e) {
if ($(this).parent().hasClass('on')) {
$(this).parent().next().slideUp();
$(this).parent().removeClass('on');
return false;
}
e.preventDefault();
$('.menu_navigation_wrap .sublist .hasSub').parent().removeClass('on');
$('.menu_navigation_wrap .sublist .subview').slideUp();
$(this).parent().next().slideToggle();
$(this).parent().toggleClass('on');
return false;
});
$(".menu_navigation_wrap .depth").on('click', function () {
/*하위레벨 없을 시 페이지 이동*/
if ($(this).closest(".isSub").find(".view").length === 0) {
const href = $(this).attr("href");
location.href = href;
}
});
//하위 카테고리 없을 시 view 클래스 삭제
$(".view").each(function(){
if($(this).find("li").length === 0){
$(this).remove();
}
});
//아이디 저장시 alert메시지 삭제
fn_hide_alertTxt('username', 'mbrIdAlertText');
});
</script>
<body>
<div class="screen-wrap">
<!-- 헤더 영역 -->
<header class="header header--sub">
<div class="header__wrapper">
<div class="header__controls-wrapper">
<div class="header__controls">
<div class="header__toBack">
<button class="header__toBack__btn" onclick="window.history.back();">
<span class="visually-hidden" >뒤로가기</span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"
viewBox="0 0 24 24">
<path fill="#1A1A1A"
d="M16.598 3.338a.75.75 0 0 0-1.061 0l-8.132 8.131a.75.75 0 0 0 0 1.061l8.132 8.132a.75.75 0 0 0 1.06-1.06L8.998 12l7.6-7.602a.75.75 0 0 0 0-1.06Z">
</path>
</svg>
</button>
</div>
<h1 class="header__title">로그인</h1>
</div>
</div>
</div>
<nav class="headerTab">
<div class="headerTab__content">
<ul class="headerTab__list">
<li class="headerTab__item active">
<a class="boxTab__tabBtn" href="javascript:void(0);">회원</a>
</li>
<li class="headerTab__item">
<a class="boxTab__tabBtn" href="javascript:void(0);">비회원(주문조회)</a>
</li>
</ul>
</div>
</nav>
</header>
<!-- 하단 탭바 -->
<aside class="tab-bar">
<nav class="tab-bar__nav">
<a class="tab-bar__link" onclick="openModal('hamburger-menu');">
<i class="icon icon_tab-bar-category"></i>
카테고리</a>
<a class="tab-bar__link" th:href="${accessUrl + '/sopmal/mpage/ordr/selectWslistInqireForm'}">
<i class="icon icon_tab-bar-wishlist"></i>
위시리스트</a>
<div class="tab-bar__home-wrapper">
<div class="tab-bar__home">
<a th:href="${accessUrl + '/index'}" class="hide-text">
<i class="icon icon_tab-bar-home"></i>
<span class="visually-hidden">홈</span>
</a>
</div>
</div>
<a class="tab-bar__link" th:href="${accessUrl + '/sopmal/ordr/selectSpbk'}">
<i class="icon icon_tab-bar-cart"></i>
장바구니</a>
<a class="tab-bar__link active" th:href="${accessUrl + '/sopmal/mpage/mbr/selectMpageMainInqire'}">
<i class="icon icon_tab-bar-mypage"></i>
마이페이지
</a>
</nav>
<div class="tab-bar__bg">
<div class="tab-bar__bg-fraction"></div>
</div>
</aside>
<!-- 메인 컨텐츠 -->
<div class="content-wrap">
<main class="main">
<div class="sub-page">
<div class="sub-box">
<div class="login">
<div class="boxTab__content login-content current">
<div class="login__logoContainer">
<a th:href="${accessUrl}">
<img th:src="@{${cdnurl}+${shopInfo.topFilCours}+'/'+${shopInfo.topSysFilNm}}" th:alt="${shopInfo.sopmalNm}">
</a>
</div>
<form id="loginForm">
<input type="hidden" id="realm" th:value="${realm}">
<input type="hidden" id="redirectUri" th:value="${redirectUri}">
<input type="hidden" id="accessUrl" th:value="${accessUrl}">
<input type="hidden" id="sopMalCd" th:value="${sopMalCd}">
<div class="login__inputBox">
<input class="input-text full " type="text" name="username" id="username" title="아이디"
placeholder="아이디" oninput="fn_hide_alertTxt('username','mbrIdAlertText');">
<p class="login__inputBox__alertText"><span id="mbrIdAlertText">아이디를 입력해 주세요.</span></p>
<input class="input-text full " type="password" name="password" id="password" title="비밀번호"
placeholder="비밀번호" onkeyup="fn_hide_alertTxt('password','mbrPwAlertText',event);">
<p class="login__inputBox__alertText"><span id="mbrPwAlertText">비밀번호를 입력해 주세요.</span></p>
</div>
<div class="login__loginBtnContainer">
<button class="btn xl full dark login__loginBtn">로그인</button>
</div>
<div class="login__misc">
<div class="b-checkbox-container">
<label class="b-checkbox is-medium checkbox">
<input type="checkbox" value="N" name="" onchange="fn_set_checkbox(this);">
<span class="check"></span>
<span class="control-label">아이디 저장</span>
</label>
</div>
<a class="login__misc__link" th:href="${accessUrl + '/sopmal/mbr/selectIdPasswordSearch'}">아이디/비밀번호 찾기</a>
</div>
</form>
<div class="login__signIn">
<p class="login__signIn__text">아직 <span th:text="${shopInfo.sopmalNm}"></span> 회원이 아니세요?</p>
<a class="login__signIn__link" th:href="${accessUrl + '/sopmal/mbr/selectJoinGuidance'}">회원가입</a>
</div>
<div class="login__sns">
<th:block th:if="${shopInfo.kakaoIntrlckAt == 'Y'}">
<button type="button" class="login__sns__btn kakao" onclick="openSocialLoginPopup('KAKAO')"><i class="icon icon_kakaoLogin"></i>카카오
로그인</button>
</th:block>
<th:block th:if="${shopInfo.naverIntrlckAt == 'Y'}">
<button type="button" class="login__sns__btn naver" onclick="openSocialLoginPopup('NAVER')"><i class="icon icon_naverLogin"></i>네이버
로그인</button>
</th:block>
<th:block th:if="${purchasingAt == 'Y'}">
<button class="login__sns__btn gray" onclick="nmbrPurchsForm()">비회원으로 구매하기</button>
</th:block>
</div>
</div>
<div class="boxTab__content login-content">
<div class="login__logoContainer">
<a th:href="${accessUrl}">
<img th:src="@{${cdnurl}+${shopInfo.topFilCours}+'/'+${shopInfo.topSysFilNm}}" th:alt="${shopInfo.sopmalNm}">
</a>
</div>
<form id="condForm">
<div class="login__inputBox">
<input class="input-text full " type="text" name="ordrInnb" id="ordrInnb" title="주문번호"
placeholder="주문번호" oninput="fn_hide_alertTxt('ordrInnb','nmbrOrdrAlertText');">
<p class="login__inputBox__alertText"><span id="nmbrOrdrAlertText">주문번호를 입력해 주세요.</span></p>
<input class="input-text number full " type="tel" name="mbtlnb" id="mbtlnb" title="휴대폰번호"
placeholder="주문 시 입력한 휴대폰번호('-'없이)" oninput="fn_hide_alertTxt('mbtlnb','nmbrPwAlertText');">
<p class="login__inputBox__alertText"><span id="nmbrPwAlertText">휴대폰번호를 입력해 주세요.</span></p>
</div>
<div class="login__loginBtnContainer">
<button type="button" class="btn xl full dark login__loginBtn" onclick="fn_select_oderNumbber();">조회</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- Top 버튼 -->
<div class="quick-menu__to-top">
<button><i class="icon icon_quick-to-top"></i>
<span class="visually-hidden">위로 가기</span>
</button>
</div>
<div class="searchPage">
<div class="searchPage__inner">
<form id="search-form">
<div class="searchPage__header">
<div class="innerSearch">
<input id="header-search-bar" name="kwrd" type="search" placeholder="검색어를 입력해 주세요" title="검색어 입력">
<button class="searchPage__textDeleteBtn">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"
xmlns="http://www.w3.org/2000/svg">
<circle cx="8.00023" cy="7.99974" r="6.93333" fill="#b3b3b3"></circle>
<path d="M5.06689 5.06641L10.9336 10.9331M5.06689 10.9331L10.9336 5.06641"
stroke="#ffffff" stroke-width="1.25" stroke-miterlimit="10"></path>
</svg>
</button>
<button id="search_btn"><i class="icon icon_nav-search"></i></button>
</div>
<div class="header-search-pop__auto-complete">
<ul>
</ul>
</div>
<button type="button" class="searchPage__closeBtn" onclick="fn_search_close();">
<span class="visually-hidden">검색어 삭제</span>
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24"
viewBox="0 0 24 24">
<path
d="M 4.9902344 3.9902344 A 1.0001 1.0001 0 0 0 4.2929688 5.7070312 L 10.585938 12 L 4.2929688 18.292969 A 1.0001 1.0001 0 1 0 5.7070312 19.707031 L 12 13.414062 L 18.292969 19.707031 A 1.0001 1.0001 0 1 0 19.707031 18.292969 L 13.414062 12 L 19.707031 5.7070312 A 1.0001 1.0001 0 0 0 18.980469 3.9902344 A 1.0001 1.0001 0 0 0 18.292969 4.2929688 L 12 10.585938 L 5.7070312 4.2929688 A 1.0001 1.0001 0 0 0 4.9902344 3.9902344 z">
</path>
</svg>
</button>
</div>
</form>
<div class="searchPage__body">
<div class="searchPage__section">
<div class="searchPage__sectionHeader">
<h5 class="searchPage__title">최근 검색어</h5>
<button class="recentSearch__deleteAll">전체삭제</button>
</div>
<div class="recentSearch">
<ul class="recentSearch__list">
</ul>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</div>
<!-- 햄버거 메뉴 모달 -->
<div class="microModal microFullMenu" id="hamburger-menu" aria-hidden="true">
<div class="microModal__overlay" tabindex="-1">
<div class="microModal__container" role="dialog" aria-modal="true">
<div class="microModal__body" id = "hambergerModal">
<div class="microModal__top">
<h2 class="microModal__title">
전체메뉴
</h2>
<button class="microModal__close" onclick="closeModal('hamburger-menu');"></button>
</div>
<div class="microModal__content">
<div class="fullMenu">
<div class="sub-box">
<div class="fullMenu__top">
<button class="btn md outline" onclick="fn_mobileButton('/login');">로그인</button>
<button class="btn md theme"onclick="fn_mobileButton('/sopmal/mbr/selectJoinGuidance');">회원가입</button>
</div>
</div>
<div class="sub-box">
<div class="fullMenu__top">
<div class="member-rank-summary">
<div class="textBtns">
<a th:href="${accessUrl + '/index'}" class="textBtns__btn">홈으로</a>
<a th:href="${accessUrl + '/sopmal/ordr/selectSpbk'}" class="textBtns__btn">장바구니</a>
<a th:href="${accessUrl + '/login'}" class="textBtns__btn">주문조회</a>
</div>
</div>
</div>
</div>
<div class="product-tab">
<ul>
<li><button class="product-tab__btn hamburgerTabBtn"></button></li>
</ul>
</div>
<div class="sub-box">
<div class="menu_navigation_wrap">
<ul class="side_menu accordion" th:if="${not category.isEmpty()}">
<th:block th:each="topMenuList : ${category}">
<th:block th:if="${topMenuList.menuExpsrAt eq 'Y'}">
<th:block th:if="${topMenuList.rnum == 2}">
<li class="isSub list">
<div class="isSubDv">
<a th:href="${accessUrl + topMenuList.url}" class="depth" th:text="${topMenuList.ctgryNm}">
<em class="visually-hidden">상세내용닫기</em>
</a>
<a th:href="${accessUrl + topMenuList.url}" class="moer"></a>
</div>
<ul class="view">
<th:block th:each="subMenu : ${category}">
<th:block th:if="${subMenu.rnum == 3}">
<th:block th:if="${topMenuList.ctgryId eq subMenu.upperCtgryId}">
<li><a th:href="${accessUrl + subMenu.url}" th:text="${subMenu.ctgryNm}"></a></li>
</th:block>
</th:block>
</th:block>
</ul>
</li>
</th:block>
</th:block>
</th:block>
</ul>
</div>
</div>
<div class="sub-box">
<div class="fullMenu__miscLinks">
<h5 class="fullMenu__miscLinks__title">서비스</h5>
<ul class="fullMenu__miscLinks__list">
<li>
<a th:href="${accessUrl + '/sopmal/csc/selectCscMainForm'}" class="fullMenu__miscLinks__link">고객센터</a>
</li>
</ul>
</div>
</div>
<div class="sub-box" th:if="${shopInfo.cscTelnbOrdrPosblAt == 'Y'}">
<div class="mainNotice__customerContact mainNotice__customerContact--moreInfo">
<i class="icon icon_notice03"></i>
<div class="mainNotice__customerContact__right">
<h4 class="notice__title customer-service">고객센터</h4>
<span class="notice__number" th:text="${shopInfo.cscTelnb}"></span>
<p class="notice__paragraph">
<span class="notice__text01" th:text="${shopInfo.cscWkdayWorkTme}"></span>
<span class="notice__text02" th:text="@{|(${shopInfo.cscLunchTme})|}"></span>
<br>
<span class="notice__text03" th:text="${shopInfo.cscRstde}"></span>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
/* ********************************************************
* 로그인
******************************************************** */
document.getElementById('loginForm').addEventListener('submit', function(e) {
e.preventDefault();
const realm = document.getElementById('realm').value;
const username = document.getElementById('username').value.replace(/\s+/g, '');
const password = document.getElementById('password').value.replace(/\s+/g, '');
const redirectUri = document.getElementById('redirectUri').value;
const accessUrl = document.getElementById('accessUrl').value;
const sopMalCd = document.getElementById('sopMalCd').value;
const id = document.querySelector("#username");
const pw = document.querySelector("#password");
let validateTarget;
//validate
if (fn_is_empty(id.value)) {
validateTarget = 'id';
} else if (fn_is_empty(pw.value)) {
validateTarget = 'pw';
}else{
validateTarget = 'none';
}
fetch(`/login/${realm}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: username,
password: password,
redirectUri: redirectUri,
accessUrl: accessUrl,
sopMalCd: sopMalCd
})
})
.then(response => {
console.log(response)
if (response.ok) {
return response;
}else{
switch(response.status){
case 401:
if(validateTarget === 'id'){
throw new Error('아이디를 입력해주세요.');
}else if(validateTarget === 'pw'){
throw new Error('비밀번호를 입력해주세요.');
}else{
throw new Error('회원아이디나 비밀번호를 다시 확인해주세요.');
}
case 404:
break;
default:
throw new Error('회원 로그인에 실패하였습니다. 관리자에게 문의해주세요.');
}
}
})
.then(data => {
console.log('Login successful', data);
let moveTo = redirectUri;
if(redirectUri === '') moveTo = '/'
window.location.href = data.url;
})
.catch(error => {
console.error('Error:', error);
alert(error.message);
if (validateTarget === 'id') {
id.focus();
} else if (validateTarget === 'pw') {
pw.focus();
}
});
});
/* ********************************************************
* 로그아웃
******************************************************** */
const logout = () => {
fetch('/logout', {
method: 'GET',
credentials: 'include'
}).then(response => {
if (response.ok) {
window.location.href = '/login';
} else {
console.error('Logout failed');
}
}).catch(error => {
console.error('Error:', error);
});
}
/* ********************************************************
* SNS 소셜 로그인
******************************************************** */
// 웹뷰 환경 감지 함수 추가
function isWebView() {
const ua = navigator.userAgent.toLowerCase();
return ua.includes('wv') ||
ua.includes('webview') ||
window.ReactNativeWebView !== undefined ||
(window.webkit && window.webkit.messageHandlers);
}
const openSocialLoginPopup = (provider) => {
console.log("openSocialLoginPopup");
var redirectUri = document.getElementById('redirectUri').value;
var sopMalCd = document.getElementById('sopMalCd').value;
var accessUrl = document.getElementById('accessUrl').value;
var tmpProvider = sopMalCd + '-' + provider;
var url = '/oauth2/authorization/' + tmpProvider +
'?access_url=' + encodeURIComponent(accessUrl) +
'&redirect_uri=' + encodeURIComponent(redirectUri) +
"&oauth2_type=login";
// 웹뷰 환경인지 확인
if (isWebView()) {
console.log("웹뷰 환경");
// 웹뷰에서는 현재 창에서 직접 리다이렉트
window.location.href = url;
} else {
console.log("일반 브라우저 환경");
// 일반 브라우저에서는 팝업 사용
var width = 600;
var height = 600;
var left = (screen.width / 2) - (width / 2);
var top = (screen.height / 2) - (height / 2);
window.open(url, 'SocialLoginPopup',
'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=' +
width + ', height=' + height + ', top=' + top + ', left=' + left);
}
}
const receiveMessage = (event) => {
if(event.origin !== window.location.origin) {
return;
}
if(event.data.type === 'LOGIN_SUCCESS') {
window.location.href = event.data.redirectUrl;
}
}
window.addEventListener('message', receiveMessage, false);
//비회원 주문 폼 이동
function nmbrPurchsForm(){
var accessUrl = document.getElementById('accessUrl').value;
window.location.href = accessUrl+'/sopmal/ordr/selectNmbrPurchsForm';
}
//로그인,주문조회 input 이벤트
function fn_hide_alertTxt(targetId, targetAlertId,event) {
const inputLen = document.querySelector("#" + targetId).value.length;
const target = document.querySelector("#" + targetAlertId);
if (inputLen > 0) {
if (targetId === 'password') {
if (event.getModifierState("CapsLock")) {
target.textContent = "Caps Lock이 켜져 있습니다.";
target.style.display = 'block';
} else {
target.style.display = 'none';
}
} else {
target.style.display = 'none';
}
} else {
if (targetId === 'password') {
target.textContent = "비밀번호를 입력해주세요.";
}
target.style.display = 'block'
}
}
//로그인/회원가입 버튼 클릭
function fn_mobileButton(url){
var accessUrl = document.getElementById('accessUrl').value;
window.location.href = accessUrl+url;
}
</script>
</body>
</html>