최초 세팅

This commit is contained in:
bd091
2025-10-18 10:53:16 +09:00
commit 3632629a76
434 changed files with 61338 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="ko"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{/admin/layout/emptyLayout}">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>error</title>
<!-- 합쳐지고 최소화된 최신 CSS -->
<link rel="stylesheet" href="/bootstrap/bootstrap-3.4.1-dist/css/bootstrap.min.css">
<!-- 부가적인 테마 -->
<link rel="stylesheet" href="/bootstrap/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css">
<!-- font awesome -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- 적용 css -->
<link rel="stylesheet" href="/css/admin/error.css">
<link rel="stylesheet" href="/css/admin/common.css">
<script src="/js/jquery.min.js"></script>
<!-- 합쳐지고 최소화된 최신 자바스크립트 -->
<script src="/bootstrap/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>
</head>
<body class="body_layout">
<!-- 네비 메뉴 -->
<div class="header">
<div class="gnb container">
<div id="header">
<div class="insideWrap">
</div>
</div>
</div>
</div>
<!-- error -->
<div class="error container" id="body">
<div class="normal">
<p class="font-title1 bd title tac">Error<img src="/image/error/icon5.png"></p>
<p class="font-title5 title tac">요청하신 페이지를 찾을수 없습니다.<br>입력하신 주소가 정확한지 다시 한번 확인해주세요.</p>
<a onclick="history.back();"><p class="font-title4 bd title tac btn">이전페이지로 돌아가기</p></a>
<div class="img"><img src="/image/error/error_img.png"></div>
</div>
</div>
<!-- 하단 -->
<div class="footer"></div>
</body>
<script>
$(function() {
$(window).resize(function() {
screenSize();
});
$('[name = "scrollTop"]').click(function() {
$('html, body').animate({
scrollTop : 0
}, 400);
return false;
});
});
</script>
<script>
$(document).ready(function(){
screenSize();
});
//모바일 화면일시 배너 크기 조정
function screenSize(){
//화면 너비
var windowWidth = $( window ).width();
//창 가로 크기가 500 미만일 경우
if(windowWidth > 769){
//화면 높이
var innerHeight = window.innerHeight;
$("#body").css("height",innerHeight-80);
}else{
//화면 높이
var innerHeight = window.innerHeight;
$("#body").css("height",innerHeight-60);
}
}
</script>

View File

@@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="ko"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{/admin/layout/emptyLayout}">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>error</title>
<!-- 합쳐지고 최소화된 최신 CSS -->
<link rel="stylesheet" href="/bootstrap/bootstrap-3.4.1-dist/css/bootstrap.min.css">
<!-- 부가적인 테마 -->
<link rel="stylesheet" href="/bootstrap/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css">
<!-- font awesome -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- 적용 css -->
<link rel="stylesheet" href="/css/admin/error.css">
<link rel="stylesheet" href="/css/admin/common.css">
<script src="/js/jquery.min.js"></script>
<!-- 합쳐지고 최소화된 최신 자바스크립트 -->
<script src="/bootstrap/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>
</head>
<body class="body_layout">
<!-- 네비 메뉴 -->
<div class="header">
<div class="gnb container">
<div id="header">
<div class="insideWrap">
</div>
</div>
</div>
</div>
<!-- error -->
<div class="error container" id="body">
<div class="normal">
<p class="font-title1 bd title tac">Error<img src="/image/error/icon5.png"></p>
<p class="font-title5 title tac">요청하신 페이지를 찾을수 없습니다.<br>입력하신 주소가 정확한지 다시 한번 확인해주세요.</p>
<a onclick="history.back();"><p class="font-title4 bd title tac btn">이전페이지로 돌아가기</p></a>
<div class="img"><img src="/image/error/error_img.png"></div>
</div>
</div>
<!-- 하단 -->
<div class="footer"></div>
</body>
<script>
$(function() {
$(window).resize(function() {
screenSize();
});
$('[name = "scrollTop"]').click(function() {
$('html, body').animate({
scrollTop : 0
}, 400);
return false;
});
});
</script>
<script>
$(document).ready(function(){
screenSize();
});
//모바일 화면일시 배너 크기 조정
function screenSize(){
//화면 너비
var windowWidth = $( window ).width();
//창 가로 크기가 500 미만일 경우
if(windowWidth > 769){
//화면 높이
var innerHeight = window.innerHeight;
$("#body").css("height",innerHeight-80);
}else{
//화면 높이
var innerHeight = window.innerHeight;
$("#body").css("height",innerHeight-60);
}
}
</script>

View File

@@ -0,0 +1,125 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/index.css">
<link rel="stylesheet" href="/css/web/instagram-swiper-custom.css?v1.0">
</th:block>
<th:block layout:fragment="layoutContent">
<div class="popup-background-mask"></div>
<main>
<section class="banner main_banner">
<div class="swiper main_banner_swiper">
<div class="swiper-wrapper" id="mainBannerList">
</div>
<div class="swiper-pagination main_banner_pagination"></div>
</div>
</section>
<section class="cont content1">
<div class="swiper-area">
<h3>
<span style="color:#fff;">MADE U</span> <span style="color:#ffcccc">시그니처</span>
</h3>
<div class="swiper cont1_swiper">
<div class="swiper-wrapper">
<div class="swiper-slide">
<img class="pc" src="/image/main-slide/signature_diet_medicine_20251001.jpg" alt="img">
<img class="mb" src="/image/main-slide/signature_diet_medicine_20251001.jpg" alt="img">
</div>
<div class="swiper-slide">
<img class="pc" src="/image/main-slide/지방분해주사_20250911.jpg" alt="img">
<img class="mb" src="/image/main-slide/지방분해주사_20250911.jpg" alt="img">
</div>
</div>
<div class="swiper-pagination cont1_swiper_pagination"></div>
</div>
</div>
</section>
<section class="banner sub_banner">
<div class="swiper sub_banner_swiper">
<div class="swiper-wrapper" id="subBannerList">
<div class="swiper-slide" style="background:#666;">
<button class="detail_btn">Detail view ></button>
</div>
<div class="swiper-slide" style="background:#999;">
<button class="detail_btn">Detail view ></button>
</div>
<div class="swiper-slide" style="background:#ddd;">
<button class="detail_btn">Detail view ></button>
</div>
</div>
<div class="swiper-pagination sub_banner_pagination"></div>
</div>
</section>
<section class="cont content2">
<div class="swiper-area">
<h3>
<span style="color:#cc3333">MADE U</span> <span style="color:#000">프리미엄장비</span>
</h3>
<div class="swiper cont2_swiper">
<div class="swiper-wrapper">
<div class="swiper-slide">
<img class="pc" src="/image/main-slide/울핏_20250911.jpg" alt="img">
<img class="mb" src="/image/main-slide/울핏_20250911.jpg" alt="img">
</div>
<div class="swiper-slide">
<img class="pc" src="/image/main-slide/튠바디_20250911.jpg" alt="img">
<img class="mb" src="/image/main-slide/튠바디_20250911.jpg" alt="img">
</div>
</div>
<div class="swiper-pagination cont2_swiper_pagination"></div>
</div>
</div>
</section>
<section class="instagram">
<div class="swiper-area">
<div class="instagram_top">
<h3>
MADE U 인스타그램<br/>
<span>@madeu_diet</span>
</h3>
<button class="more_btn" onClick="window.open('https://instagram.com/madeu_diet')">View more ≫</button>
</div>
<div class="instagram_btm" id="instagramFeed">
<div class="swiper instagram_swiper">
<div class="swiper-wrapper" id="instagramList">
</div>
</div>
<!-- 커스텀 내비게이션 하단 영역 -->
<div class="instagram-swiper-footer">
<button class="custom-swiper-btn prev"></button>
<div class="custom-swiper-thumbs"></div>
<button class="custom-swiper-btn next"></button>
</div>
</div>
</div>
</section>
</main>
<!-- 팝업 -->
<div class="popup">
<div class="top">
<div class="tab-content" id="popupContentList"></div>
<ul class="nav nav-tabs" role="tablist" id="popupTabList"></ul>
</div>
<div class="btm">
<div class="left_box">
<input type="checkbox" id="today"/>
<label for="today">오늘 하루 안보기</label>
</div>
<div class="right_box">
<button class="close_btn_btm" id="btnPopupClose"><img src="/image/web/close.png" alt="close"/></button>
</div>
</div>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
<script>
// CDN_URL 전역 정의
const CDN_URL = "[(${@environment.getProperty('url.cdn')})]";
</script>
<script src="/js/web/index.js"></script>
</th:block>
</html>

View File

@@ -0,0 +1,603 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MADEU - Premium Skincare Center</title>
<script src="https://code.jquery.com/jquery-1.12.4.js" integrity="sha256-Qw82+bXyGq6MydymqBxNPYTaUXXq7c8v3CwiYwLLNXU=" crossorigin="anonymous"></script>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700&display=swap" rel="stylesheet">
<style type="text/css">
/* 기본 리셋 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
height: 100%;
width: 100%;
font-family: 'Noto Sans KR', sans-serif;
scroll-behavior: smooth;
overflow-x: hidden;
}
/* 메인 컨테이너 */
.main-container {
position: relative;
width: 100%;
min-height: 100vh;
background: #222222;
overflow: hidden;
padding: 80px 20px 40px;
}
/* 애니메이션 키프레임 */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(50px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 헤더 */
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: #fff;
backdrop-filter: blur(20px);
z-index: 1000;
padding: 15px 0;
transition: all 0.3s ease;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}
.header-content {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
display: flex;
justify-content: center;
align-items: center;
}
.logo {
font-size: 28px;
font-weight: 700;
color: #333;
text-decoration: none;
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
cursor: pointer;
}
/* 메인 콘텐츠 */
.content-wrapper {
max-width: 1200px;
margin: 0 auto;
display: flex;
height: calc(100vh - 120px);
position: relative;
z-index: 2;
gap: 40px;
align-items: center;
}
.split {
flex: 1;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
transition: all 0.8s cubic-bezier(0.23, 1, 0.320, 1);
}
.split:hover {
transform: scale(1.05);
}
/* 비디오 컨테이너 */
.video-container {
position: relative;
width: 600px;
height: 675px;
border-radius: 25px;
overflow: hidden;
box-shadow:
0 20px 60px rgba(0, 0, 0, 0.5),
0 8px 25px rgba(0, 0, 0, 0.3);
transition: all 0.8s ease;
}
.split:hover .video-container {
box-shadow:
0 30px 80px rgba(0, 0, 0, 0.6),
0 12px 35px rgba(0, 0, 0, 0.4);
transform: translateY(-10px);
}
.fullscreen-video {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.8s ease;
transform-origin: top center;
}
.split:hover .fullscreen-video {
transform: scale(1.1);
}
/* 오버레이 */
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
180deg,
transparent 0%,
transparent 60%,
rgba(0, 0, 0, 0.6) 100%
);
border-radius: 25px;
transition: all 0.8s ease;
}
.split:hover .overlay {
background: linear-gradient(
180deg,
transparent 0%,
transparent 60%,
rgba(0, 0, 0, 0.4) 100%
);
}
/* 센터 정보 - 영상 하단에 절대 위치로 배치 */
.center-info {
position: absolute;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
text-align: center;
color: white;
z-index: 10;
}
.center-title {
font-size: 28px;
font-weight: 700;
margin-bottom: 15px;
text-shadow: 0 4px 15px rgba(0, 0, 0, 0.8);
background: linear-gradient(135deg, #fff, #f0f0f0);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.center-subtitle {
font-size: 16px;
font-weight: 400;
opacity: 0.95;
margin-bottom: 20px;
text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
line-height: 1.4;
}
.enter-button {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.7));
border: none;
padding: 15px 35px;
border-radius: 30px;
font-size: 14px;
font-weight: 600;
color: #333;
cursor: pointer;
transition: all 0.4s cubic-bezier(0.23, 1, 0.320, 1);
box-shadow:
0 12px 30px rgba(0, 0, 0, 0.3),
inset 0 2px 0 rgba(255, 255, 255, 0.5),
inset 0 -2px 0 rgba(0, 0, 0, 0.1);
text-transform: uppercase;
letter-spacing: 1px;
backdrop-filter: blur(10px);
border: 2px solid rgba(255, 255, 255, 0.3);
position: relative;
overflow: hidden;
margin-bottom: 15px;
}
.enter-button::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg,
transparent,
rgba(255, 255, 255, 0.4),
transparent);
transition: left 0.5s ease;
}
.enter-button:hover::before {
left: 100%;
}
.enter-button:hover {
background: linear-gradient(135deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0.9));
transform: translateY(-5px);
box-shadow:
0 20px 50px rgba(0, 0, 0, 0.4),
inset 0 2px 0 rgba(255, 255, 255, 0.7),
inset 0 -2px 0 rgba(0, 0, 0, 0.1);
}
.enter-button:active {
transform: translateY(-2px) scale(0.98);
}
/* 로딩 애니메이션 */
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #1a0000;
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
opacity: 1;
transition: opacity 1s ease;
}
.loading-overlay.hidden {
opacity: 0;
pointer-events: none;
}
.loading-spinner {
width: 60px;
height: 60px;
border: 3px solid rgba(255, 255, 255, 0.3);
border-top: 3px solid white;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 모바일 반응형 디자인 */
@media screen and (max-width: 1280px) {
.video-container {
width: 450px;
height: 506px;
}
.center-info {
bottom: 25px;
}
}
@media screen and (max-width: 768px) {
.main-container {
padding: 80px 15px 30px;
}
.header {
padding: 12px 0;
}
.logo {
font-size: 24px;
}
.content-wrapper {
flex-direction: column;
height: auto;
gap: 60px;
padding: 30px 0;
align-items: center;
}
.video-container {
width: 320px;
height: 360px;
}
.center-info {
bottom: 20px;
padding: 0 15px;
width: calc(100% - 30px);
}
.center-title {
font-size: 24px;
}
.center-subtitle {
font-size: 15px;
margin-bottom: 15px;
}
.enter-button {
padding: 12px 30px;
font-size: 13px;
letter-spacing: 0.5px;
margin-bottom: 10px;
}
}
@media screen and (max-width: 480px) {
.header-content {
padding: 0 15px;
}
.logo {
font-size: 20px;
}
.video-container {
width: 280px;
height: 315px;
border-radius: 20px;
}
.center-info {
bottom: 15px;
padding: 0 10px;
width: calc(100% - 20px);
}
.center-title {
font-size: 20px;
margin-bottom: 10px;
}
.center-subtitle {
font-size: 14px;
line-height: 1.3;
margin-bottom: 0;
}
.enter-button {
padding: 10px 25px;
font-size: 12px;
margin-bottom: 8px;
}
.content-wrapper {
gap: 50px;
padding: 20px 0;
}
}
/* 터치 디바이스 최적화 */
@media (hover: none) and (pointer: coarse) {
.enter-button:hover {
transform: translateY(0);
}
.enter-button:active {
transform: scale(0.95);
}
.split:hover {
transform: none;
}
.split:hover .video-container {
transform: none;
box-shadow:
0 20px 60px rgba(0, 0, 0, 0.5),
0 8px 25px rgba(0, 0, 0, 0.3);
}
.split:hover .fullscreen-video {
transform: scale(1);
}
.split.touch-active .video-container {
transform: translateY(-5px);
}
.split.touch-active .fullscreen-video {
transform: scale(1.05);
}
}
/* 아이폰 Safe Area 대응 */
@supports (padding: max(0px)) {
.header {
padding-left: max(20px, env(safe-area-inset-left));
padding-right: max(20px, env(safe-area-inset-right));
}
.main-container {
padding-bottom: max(40px, env(safe-area-inset-bottom));
}
}
/* 다크 모드 지원 */
@media (prefers-color-scheme: dark) {
.header {
background: rgba(20, 20, 30, 0.95);
}
.logo {
color: white;
}
}
</style>
<script th:inline="javascript">
/*<![CDATA[*/
const activeProfile = /*[[${@environment.getActiveProfiles().length > 0 ? @environment.getActiveProfiles()[0] : 'local'}]]*/;
console.log("[environment] :" + activeProfile);
/*]]>*/
</script>
</head>
<body>
<!-- 로딩 오버레이 -->
<div class="loading-overlay" id="loadingOverlay">
<div class="loading-spinner"></div>
</div>
<!-- 헤더 -->
<header class="header">
<div class="header-content">
<a href="javascript:fn_logoClick()" class="logo">
<img src="/image/logo_121x33.png" alt="메이드유">
</a>
</div>
</header>
<!-- 메인 컨테이너 -->
<div class="main-container">
<!-- 콘텐츠 래퍼 -->
<div class="content-wrapper">
<!-- 다이어트 센터 -->
<div class="split left" id="dietCenter">
<div class="video-container">
<video autoplay muted loop class="fullscreen-video" playsinline>
<source src="/image/index/diet_center_960x1080.mp4" type="video/mp4">
</video>
<div class="overlay"></div>
<!-- 여기가 중요! video-container 안에 center-info 위치 -->
<div class="center-info">
<button class="enter-button" onclick="dietCenterBtn()">
Enter Diet Center
</button>
<p class="center-subtitle">체계적인 체중관리와 건강한 라이프스타일</p>
</div>
</div>
</div>
<!-- 쁘띠&스킨센터 -->
<div class="split right" id="petitCenter">
<div class="video-container">
<video autoplay muted loop class="fullscreen-video" playsinline>
<source src="/image/index/petit_skin_center_960x1080.mp4" type="video/mp4">
</video>
<div class="overlay"></div>
<!-- 여기도 video-container 안에 center-info 위치 -->
<div class="center-info">
<button class="enter-button" onclick="petitSkinCenterBtn()">
Enter Petit Center
</button>
<p class="center-subtitle">프리미엄 스킨케어와 미용 전문 서비스</p>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
// 로딩 애니메이션
window.addEventListener('load', function() {
setTimeout(function() {
document.getElementById('loadingOverlay').classList.add('hidden');
}, 1000);
});
// 버튼 클릭 함수들
function dietCenterBtn() {
const button = event.target;
button.style.transform = 'scale(0.95)';
setTimeout(() => {
location.href = getEnvironment("diet");
}, 150);
}
function petitSkinCenterBtn() {
const button = event.target;
button.style.transform = 'scale(0.95)';
setTimeout(() => {
location.href = getEnvironment("petit");
}, 150);
}
function getEnvironment(home) {
let returnUrl = "";
if(activeProfile == "local") {
if(home == "diet") {
returnUrl = "http://localhost:8081/index";
} else {
returnUrl = "http://localhost:8082/index";
}
} else if(activeProfile == "dev") {
returnUrl = "http://d" + home + ".vara.co.kr/index";
} else if(activeProfile == "prod") {
returnUrl = "https://" + home + ".madeu.co.kr/index";
} else {
returnUrl = "https://crm.vara.co.kr/";
}
return returnUrl;
}
// 스크롤 헤더 효과
window.addEventListener('scroll', function() {
const header = document.querySelector('.header');
if(window.scrollY > 50) {
header.style.background = 'rgba(255, 255, 255, 0.98)';
header.style.boxShadow = '0 5px 20px rgba(0, 0, 0, 0.1)';
} else {
header.style.background = 'rgba(255, 255, 255, 0.95)';
header.style.boxShadow = 'none';
}
});
// 페이지 초기화
document.addEventListener('DOMContentLoaded', function() {
// 터치 디바이스 최적화
if('ontouchstart' in window) {
document.querySelectorAll('.split').forEach(split => {
split.addEventListener('touchstart', function() {
this.classList.add('touch-active');
});
split.addEventListener('touchend', function() {
setTimeout(() => {
this.classList.remove('touch-active');
}, 300);
});
});
}
// 모바일에서 비디오 자동재생 확인
const videos = document.querySelectorAll('video');
videos.forEach(video => {
video.addEventListener('loadedmetadata', function() {
this.play().catch(e => {
console.log('Video autoplay failed:', e);
});
});
});
});
function fn_logoClick(){
alert("감사합니다. 메이드유 홈페이지 입니다.");
}
</script>
</body>
</html>

View File

@@ -0,0 +1 @@
[(${message})]

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 MiB

View File

@@ -0,0 +1,299 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>메쉬다 D/S 시술예약 상세페이지</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* { box-sizing: border-box; }
body {
font-family: 'Noto Sans KR', sans-serif;
margin: 0;
background: #f7f7f9;
color: #222;
}
header {
background: #fff;
border-bottom: 1px solid #ececec;
padding: 14px 0 14px 24px;
font-size: 0.98em;
color: #888;
}
.main-wrap {
max-width: 1000px;
margin: 0 auto;
background: #fff;
border-radius: 18px;
box-shadow: 0 2px 12px rgba(0,0,0,0.07);
margin-top: 32px;
padding: 0 0 32px 0;
}
.top-section {
display: flex;
flex-wrap: wrap;
gap: 32px;
padding: 32px 32px 0 32px;
align-items: flex-start;
}
.img-box {
flex: 0 0 460px;
width: 460px;
height: 470px;
background: #e9e9ef;
border-radius: 18px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.img-box img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 18px;
}
.info-box {
flex: 1 1 300px;
min-width: 240px;
}
.info-title {
font-size: 1.7em;
font-weight: 700;
margin-bottom: 6px;
color: #222;
}
.info-desc {
color: #444;
font-size: 1.1em;
margin-bottom: 18px;
}
.info-price {
font-size: 1.2em;
font-weight: 700;
color: #b23c3c;
margin-bottom: 18px;
}
.select-row {
margin-bottom: 18px;
}
.select-row label {
font-weight: 500;
margin-right: 8px;
}
.select-row select {
padding: 7px 12px;
border-radius: 6px;
border: 1px solid #ddd;
font-size: 1em;
}
.total-row {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 1.1em;
margin-bottom: 18px;
}
.total-row .total-label {
color: #888;
}
.total-row .total-price {
font-weight: bold;
color: #b23c3c;
}
.reserve-btn {
width: 100%;
padding: 14px 0;
background: #b23c3c;
color: #fff;
border: none;
border-radius: 8px;
font-size: 1.1em;
font-weight: bold;
cursor: pointer;
transition: background 0.15s;
}
.reserve-btn:disabled {
background: #ddd;
color: #888;
cursor: not-allowed;
}
.desc-section {
margin-top: 36px;
padding: 0 32px;
}
.desc-title {
font-size: 1.25em;
font-weight: 700;
margin-bottom: 12px;
color: #222;
}
.desc-content {
color: #444;
font-size: 1.05em;
line-height: 1.7;
margin-bottom: 20px;
}
.hashtag-section {
margin-top: 30px;
padding: 20px 0;
border-top: 1px solid #eee;
}
.hashtag-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.hashtag-title {
font-size: 18px;
font-weight: bold;
color: #333;
margin-bottom: 15px;
}
.hashtag-list {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.hashtag {
display: inline-block;
background-color: #f8f9fa;
color: #495057;
padding: 8px 15px;
border-radius: 20px;
font-size: 14px;
text-decoration: none;
border: 1px solid #dee2e6;
transition: all 0.3s ease;
}
.hashtag:hover {
background-color: #007bff;
color: white;
border-color: #007bff;
cursor: pointer;
}
/* 모바일 반응형 */
@media (max-width: 768px) {
.hashtag {
font-size: 12px;
padding: 6px 12px;
}
.hashtag-list {
gap: 8px;
}
}
@media (max-width: 900px) {
.main-wrap { margin-top: 16px; }
.top-section { flex-direction: column; gap: 18px; padding: 20px 10px 0 10px; }
.img-box { width: 100%; height: 200px; }
.info-box { min-width: unset; }
.desc-section { padding: 0 10px; }
}
@media (max-width: 600px) {
.main-wrap { margin-top: 0; border-radius: 0; box-shadow: none; }
.top-section { padding: 12px 2vw 0 2vw; }
.desc-section { padding: 0 2vw; }
.img-box { height: 140px; }
}
</style>
</head>
<body>
<header>
시술안내/가격 &nbsp;&gt;&nbsp; 메쉬다 다이어트 주사(지방분해주사) &nbsp;&gt;&nbsp; 메쉬다 D/S
</header>
<div class="main-wrap">
<div class="top-section">
<div class="img-box">
<img src="https://images.unsplash.com/photo-1517841905240-472988babdf9?auto=format&fit=facearea&w=400&h=400" alt="시술 이미지">
</div>
<div class="info-box">
<div class="info-title">메쉬다 D/S</div>
<div class="info-desc">전신 라인 정리에 특화된 메쉬다 바디주사!</div>
<!-- 기존 info-desc 영역 하단에 추가 -->
<div class="hashtag-section">
<div class="hashtag-container">
<!-- <h3 class="hashtag-title">관련 해시태그</h3>-->
<div class="hashtag-list">
<span class="hashtag">#메쉬다바디주사</span>
<span class="hashtag">#쥬베룩</span>
<span class="hashtag">#바디라인정리</span>
<span class="hashtag">#콜라겐부스터</span>
<span class="hashtag">#전신시술</span>
<span class="hashtag">#자연스러운볼륨</span>
<span class="hashtag">#빠른회복</span>
<span class="hashtag">#합리적가격</span>
</div>
</div>
</div>
<div class="info-price"><span id="price">0</span>원 부터</div>
<div class="select-row">
<label for="procedure">시술 선택</label>
<select id="procedure">
<option value="0">선택하세요.</option>
<option value="meshda-ds">메쉬다 D/S</option>
<option value="meshda-s">메쉬다 S</option>
<option value="meshda-d">메쉬다 D</option>
</select>
</div>
<div class="total-row">
<span class="total-label">총 금액</span>
<span class="total-price" id="total">0원</span>
</div>
<button class="reserve-btn" id="reserve-btn" disabled>시술 예약하기</button>
</div>
</div>
<div class="desc-section">
<div class="desc-title">쥬베룩이란?</div>
<div class="desc-content">
고분자 PLA와 인체 피부 조직에 존재하는 히알루론산을 결합시킨 자가 조직 재생 콜라겐 부스터입니다.<br>
피부에 주입된 후 바로 볼륨 효과가 나타나는 다른 필러와는 달리 자가 콜라겐 생성을 촉진하여 자연스러운 볼륨과 탄력을 부여합니다.<br>
<br>
<b>시술 특징</b><br>
- 전신 바디 라인 정리에 특화<br>
- 빠른 시술과 회복, 일상생활 복귀 용이<br>
- 0원부터 시작하는 합리적 가격<br>
<img src="detail.jpg" width="100%" />
</div>
</div>
</div>
<script>
// 시술별 가격 정보
const priceMap = {
"0": 0,
"meshda-ds": 0,
"meshda-s": 50000,
"meshda-d": 70000
};
const procedureSelect = document.getElementById('procedure');
const priceEl = document.getElementById('price');
const totalEl = document.getElementById('total');
const reserveBtn = document.getElementById('reserve-btn');
function updatePrice() {
const val = procedureSelect.value;
const price = priceMap[val] || 0;
priceEl.textContent = price.toLocaleString();
totalEl.textContent = price.toLocaleString() + '원';
reserveBtn.disabled = val === "0";
}
procedureSelect.addEventListener('change', updatePrice);
reserveBtn.addEventListener('click', function() {
alert('시술 예약이 완료되었습니다.');
procedureSelect.value = "0";
updatePrice();
});
// 초기화
updatePrice();
</script>
</body>
</html>

View File

@@ -0,0 +1,394 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>시술 예약 시스템</title>
<style>
* { box-sizing: border-box; }
body {
font-family: 'Noto Sans KR', sans-serif;
margin: 0;
background: #fafafa;
color: #222;
}
.container {
display: flex;
gap: 16px;
padding: 24px;
max-width: 1200px;
margin: 0 auto;
}
.box {
background: #fff;
border-radius: 16px;
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
padding: 24px 16px;
flex: 1 1 0;
min-width: 260px;
display: flex;
flex-direction: column;
min-height: 600px;
}
.step-title {
color: #b23c3c;
font-weight: 700;
font-size: 1.1em;
margin-bottom: 12px;
letter-spacing: 0.02em;
}
/* 좌측 - 시술예약 */
.service-list {
flex: 1;
margin-bottom: 24px;
}
.service-item {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 1.1em;
margin-bottom: 10px;
}
.service-item .del {
cursor: pointer;
color: #b23c3c;
margin-left: 8px;
font-size: 1.2em;
}
.service-item .price {
font-weight: bold;
color: #b23c3c;
}
.total {
border-top: 1px solid #eee;
margin-top: auto;
padding-top: 16px;
display: flex;
justify-content: space-between;
font-size: 1.1em;
font-weight: bold;
}
.total .price {
color: #b23c3c;
}
.total small {
font-weight: normal;
color: #888;
font-size: 0.9em;
margin-right: 8px;
}
/* 가운데 - 예약시간선택 */
.calendar-box {
margin-bottom: 20px;
}
.calendar-header {
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
margin-bottom: 8px;
}
.calendar-header button {
background: none;
border: none;
font-size: 1.2em;
cursor: pointer;
color: #b23c3c;
padding: 0 6px;
}
.calendar-table {
width: 100%;
border-collapse: collapse;
text-align: center;
margin-bottom: 8px;
}
.calendar-table th, .calendar-table td {
width: 2em;
height: 2em;
padding: 2px;
font-size: 1em;
border-radius: 50%;
cursor: pointer;
transition: background 0.15s;
}
.calendar-table th {
color: #b23c3c;
font-weight: 500;
background: none;
}
.calendar-table td.selected {
background: #b23c3c;
color: #fff;
}
.calendar-table td.today {
border: 1.5px solid #b23c3c;
}
.calendar-table td:not(.selected):hover {
background: #f5eaea;
}
.calendar-table td.disabled {
color: #ccc;
pointer-events: none;
background: none;
}
.time-slots {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 12px;
}
.time-btn {
flex: 1 0 30%;
min-width: 80px;
padding: 8px 0;
border: 1px solid #b23c3c;
border-radius: 20px;
background: #fff;
color: #b23c3c;
font-size: 1em;
cursor: pointer;
transition: background 0.15s, color 0.15s;
}
.time-btn.selected, .time-btn:active {
background: #b23c3c;
color: #fff;
}
.time-btn:disabled {
color: #ccc;
border-color: #eee;
background: #f5f5f5;
cursor: not-allowed;
}
.person-count {
margin-top: 12px;
font-size: 0.98em;
color: #888;
}
/* 우측 - 고객정보 */
.form-group {
margin-bottom: 16px;
}
.form-group label {
display: block;
margin-bottom: 4px;
font-weight: 500;
}
.form-group input, .form-group textarea {
width: 100%;
padding: 8px 10px;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 1em;
resize: none;
}
.form-group textarea {
min-height: 60px;
}
.checkbox-group {
display: flex;
align-items: center;
margin-bottom: 18px;
font-size: 0.98em;
}
.checkbox-group input[type="checkbox"] {
margin-right: 8px;
accent-color: #b23c3c;
}
.submit-btn {
width: 100%;
padding: 14px 0;
background: #b23c3c;
color: #fff;
border: none;
border-radius: 8px;
font-size: 1.1em;
font-weight: bold;
cursor: pointer;
transition: background 0.15s;
}
.submit-btn:disabled {
background: #ddd;
color: #888;
cursor: not-allowed;
}
@media (max-width: 900px) {
.container { flex-direction: column; gap: 24px; }
.box { min-height: unset; }
}
@media (max-width: 600px) {
.container { padding: 8px; }
.box { padding: 16px 6px; }
.calendar-table th, .calendar-table td { width: 1.5em; height: 1.5em; }
.time-btn { min-width: 60px; font-size: 0.95em; }
}
</style>
</head>
<body>
<div class="container">
<!-- 좌측: 시술 예약 -->
<div class="box" id="box-service">
<div class="step-title">STEP 01. 시술 예약</div>
<div class="service-list" id="service-list">
<div class="service-item">
<span>다이어트약처방</span>
<span>
<span style="text-decoration:line-through; color:#bbb; font-size:0.95em; margin-right:6px;">50,000원</span>
<span class="price">50,000원</span>
<span class="del" title="삭제" onclick="removeService(this)">×</span>
</span>
</div>
</div>
<div class="total">
<span>총 금액 <small>(부가세 별도)</small></span>
<span class="price" id="total-price">50,000원</span>
</div>
<div style="font-size:0.9em; color:#aaa; margin-top:8px;">결제는 내원시 이루어집니다.</div>
</div>
<!-- 가운데: 예약 시간 선택 -->
<div class="box" id="box-calendar">
<div class="step-title">STEP 02. 예약 시간 선택</div>
<div class="calendar-box">
<div class="calendar-header">
<button id="prev-month" aria-label="이전 달">&lt;</button>
<span id="calendar-title" style="font-weight:600;"></span>
<button id="next-month" aria-label="다음 달">&gt;</button>
</div>
<table class="calendar-table" id="calendar-table">
<!-- JS로 렌더링 -->
</table>
</div>
<div class="time-slots" id="time-slots">
<!-- JS로 렌더링 -->
</div>
<div class="person-count">예약인원 <span id="person-count">-</span></div>
</div>
<!-- 우측: 고객정보 입력 -->
<div class="box" id="box-info">
<div class="step-title">STEP 03. 고객정보</div>
<form id="reserve-form" autocomplete="off">
<div class="form-group">
<label for="customer-name">고객명</label>
<input type="text" id="customer-name" name="customer-name" required>
</div>
<div class="form-group">
<label for="customer-phone">연락처</label>
<input type="tel" id="customer-phone" name="customer-phone" placeholder="고객님의 핸드폰 번호를 입력해 주세요." required pattern="^01[0-9]{8,9}$">
</div>
<div class="form-group">
<label for="customer-req">요청사항</label>
<textarea id="customer-req" name="customer-req" placeholder="요청사항을 작성해 주세요."></textarea>
</div>
<div class="checkbox-group">
<input type="checkbox" id="agree" required>
<label for="agree">[필수] 서비스 이용 및 예약 신청을 위한 개인정보 제공에 동의</label>
</div>
<button type="submit" class="submit-btn" id="submit-btn" disabled>시술 예약하기</button>
</form>
</div>
</div>
<script>
// 시술 삭제
function removeService(el) {
el.closest('.service-item').remove();
document.getElementById('total-price').textContent = '0원';
}
// 캘린더 데이터
const today = new Date();
let selectedYear = today.getFullYear();
let selectedMonth = today.getMonth();
let selectedDay = today.getDate();
let selectedDate = null;
let selectedTime = null;
const calendarTitle = document.getElementById('calendar-title');
const calendarTable = document.getElementById('calendar-table');
const timeSlots = document.getElementById('time-slots');
const personCount = document.getElementById('person-count');
function renderCalendar(year, month) {
calendarTitle.textContent = `${year}.${(month+1).toString().padStart(2,'0')}`;
const firstDay = new Date(year, month, 1);
const lastDay = new Date(year, month+1, 0);
let html = '<thead><tr>';
['일','월','화','수','목','금','토'].forEach(d=>html+=`<th>${d}</th>`);
html += '</tr></thead><tbody><tr>';
for(let i=0; i<firstDay.getDay(); i++) html += '<td class="disabled"></td>';
for(let d=1; d<=lastDay.getDate(); d++) {
const dateObj = new Date(year, month, d);
let classes = [];
if(dateObj.toDateString() === today.toDateString()) classes.push('today');
if(selectedDate && dateObj.toDateString() === selectedDate.toDateString()) classes.push('selected');
html += `<td class="${classes.join(' ')}" onclick="selectDate(${year},${month},${d})">${d}</td>`;
if((firstDay.getDay()+d)%7===0 && d!==lastDay.getDate()) html += '</tr><tr>';
}
for(let i=(lastDay.getDay()+1)%7; i && i<7; i++) html += '<td class="disabled"></td>';
html += '</tr></tbody>';
calendarTable.innerHTML = html;
}
function selectDate(y, m, d) {
selectedDate = new Date(y, m, d);
renderCalendar(y, m);
renderTimeSlots();
}
document.getElementById('prev-month').onclick = function() {
if(selectedMonth===0) { selectedYear--; selectedMonth=11; }
else selectedMonth--;
renderCalendar(selectedYear, selectedMonth);
renderTimeSlots();
};
document.getElementById('next-month').onclick = function() {
if(selectedMonth===11) { selectedYear++; selectedMonth=0; }
else selectedMonth++;
renderCalendar(selectedYear, selectedMonth);
renderTimeSlots();
};
// 시간 선택
const times = [
"09:00","09:30","10:00","10:30","11:00","11:30","12:00","12:30",
"13:00","13:30","14:00","14:30"
];
function renderTimeSlots() {
let html = '';
times.forEach(t=>{
html += `<button type="button" class="time-btn${selectedTime===t?' selected':''}" onclick="selectTime('${t}')">${t}</button>`;
});
timeSlots.innerHTML = html;
personCount.textContent = selectedDate ? 1 : '-';
}
window.selectTime = function(t) {
selectedTime = t;
renderTimeSlots();
}
// 날짜 선택 초기화
selectDate(today.getFullYear(), today.getMonth(), today.getDate());
// 폼 유효성 및 동의 체크
const form = document.getElementById('reserve-form');
const agree = document.getElementById('agree');
const submitBtn = document.getElementById('submit-btn');
form.addEventListener('input', checkForm);
agree.addEventListener('change', checkForm);
function checkForm() {
const name = document.getElementById('customer-name').value.trim();
const phone = document.getElementById('customer-phone').value.trim();
const valid = name && phone.match(/^01[0-9]{8,9}$/) && agree.checked;
submitBtn.disabled = !valid;
}
form.onsubmit = function(e) {
e.preventDefault();
if(!selectedDate || !selectedTime) {
alert('예약 날짜와 시간을 선택해 주세요.');
return;
}
alert('예약이 완료되었습니다.');
form.reset();
submitBtn.disabled = true;
};
</script>
</body>
</html>

View File

@@ -0,0 +1,297 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>이벤트 안내 목록</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* { box-sizing: border-box; }
body {
margin: 0;
font-family: 'Noto Sans KR', sans-serif;
background: #f7f7f9;
color: #222;
}
.container {
max-width: 1100px;
margin: 0 auto;
padding: 0 16px 40px 16px;
}
.sidebar {
width: 220px;
background: #fff;
border-radius: 16px;
box-shadow: 0 2px 10px rgba(0,0,0,0.06);
padding: 24px 16px;
margin-right: 32px;
min-width: 180px;
}
.sidebar .menu-title {
font-weight: 700;
color: #b23c3c;
margin-bottom: 16px;
font-size: 1.1em;
}
.sidebar .menu-list {
list-style: none;
padding: 0;
margin: 0;
}
.sidebar .menu-list li {
margin-bottom: 10px;
}
.sidebar .menu-list button {
width: 100%;
background: none;
border: none;
text-align: left;
padding: 8px 0;
font-size: 1em;
color: #444;
cursor: pointer;
border-radius: 6px;
transition: background 0.13s;
}
.sidebar .menu-list button.active,
.sidebar .menu-list button:hover {
background: #f5eaea;
color: #b23c3c;
font-weight: 600;
}
.main-content {
flex: 1 1 0;
min-width: 260px;
}
.event-list {
display: flex;
flex-direction: column;
gap: 32px;
}
.event-card {
display: flex;
background: #fff;
border-radius: 16px;
box-shadow: 0 2px 10px rgba(0,0,0,0.07);
overflow: hidden;
align-items: stretch;
transition: box-shadow 0.15s;
}
.event-card:hover {
box-shadow: 0 6px 18px rgba(178,60,60,0.13);
}
.event-img {
width: 220px;
min-width: 120px;
background: #e9e9ef;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.event-img img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.event-info {
flex: 1 1 0;
padding: 24px 26px 24px 24px;
display: flex;
flex-direction: column;
justify-content: center;
}
.event-title {
font-size: 1.25em;
font-weight: 700;
margin-bottom: 8px;
color: #222;
}
.event-desc {
color: #444;
font-size: 1em;
margin-bottom: 10px;
}
.event-meta {
font-size: 0.97em;
color: #888;
margin-bottom: 16px;
}
.event-price {
font-size: 1.15em;
color: #b23c3c;
font-weight: 700;
margin-bottom: 8px;
}
.event-link {
align-self: flex-end;
background: #b23c3c;
color: #fff;
border: none;
border-radius: 8px;
padding: 8px 18px;
font-size: 1em;
cursor: pointer;
transition: background 0.13s;
text-decoration: none;
}
.event-link:hover {
background: #a12f2f;
}
@media (max-width: 900px) {
.layout {
flex-direction: column;
}
.sidebar {
margin-right: 0;
margin-bottom: 24px;
width: 100%;
min-width: unset;
}
.event-card {
flex-direction: column;
}
.event-img {
width: 100%;
height: 180px;
}
}
@media (max-width: 600px) {
.container {
padding: 0 2vw 24px 2vw;
}
.sidebar {
padding: 16px 6px;
border-radius: 10px;
}
.event-card {
border-radius: 10px;
}
.event-info {
padding: 16px 10px 16px 10px;
}
.event-img {
height: 120px;
}
}
</style>
</head>
<body>
<div class="container">
<div class="layout" style="display: flex; gap: 32px; align-items: flex-start;">
<!-- Sidebar -->
<aside class="sidebar">
<div class="menu-title">이달의 이벤트</div>
<ul class="menu-list">
<li><button class="active">이달의 이벤트</button></li>
<li><button>압구정 인기 BEST 10 시술</button></li>
<li><button>1년 동안 1:1 맞춤관리</button></li>
<li><button>보톡스 통째로 100유닛</button></li>
<li><button>BEST 볼륨 필러 이벤트</button></li>
<li><button>BEST 스킨 부스터 이벤트</button></li>
<li><button>BEST 지방분해 [바디] 이벤트</button></li>
<li><button>BEST 색소 / 여드름 / 피부결 이벤트</button></li>
</ul>
</aside>
<!-- Main Content -->
<main class="main-content">
<div class="event-list" id="event-list">
<!-- 이벤트 카드가 JS로 렌더링됩니다 -->
</div>
</main>
</div>
</div>
<script>
// 샘플 이벤트 데이터
const events = [
{
img: "https://images.unsplash.com/photo-1518717758536-85ae29035b6d?auto=format&fit=facearea&w=400&h=250",
title: "대표원장님: 여름 휴가 이벤트 ♥",
desc: "휴가 떠나기 전, 나를 위한 선물!",
meta: "SUMMER EVENT",
price: { before: 190000, after: 100000 },
link: "#"
},
{
img: "https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=facearea&w=400&h=250",
title: "무더위와 장마에도 빛나는 네 피부를 사랑해!",
desc: "무더위에도, 습한 장마에도 살아 남는",
meta: "7.1 ~ 7.31",
price: { before: 59999, after: 30000 },
link: "#"
},
{
img: "https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=facearea&w=400&h=250",
title: "평일 오후 1시-5시 / 피부 이벤트",
desc: "월,화,목,금 1.5시 한정 피부 이벤트",
meta: "",
price: { before: 75000, after: 39000 },
link: "#"
}
];
// 이벤트 카드 렌더링
function renderEvents() {
const list = document.getElementById('event-list');
list.innerHTML = '';
events.forEach(ev => {
const card = document.createElement('div');
card.className = 'event-card';
const imgBox = document.createElement('div');
imgBox.className = 'event-img';
const img = document.createElement('img');
img.src = ev.img;
img.alt = ev.title;
imgBox.appendChild(img);
const info = document.createElement('div');
info.className = 'event-info';
const title = document.createElement('div');
title.className = 'event-title';
title.textContent = ev.title;
const desc = document.createElement('div');
desc.className = 'event-desc';
desc.textContent = ev.desc;
const meta = document.createElement('div');
meta.className = 'event-meta';
meta.textContent = ev.meta;
const price = document.createElement('div');
price.className = 'event-price';
price.innerHTML = `<span style="text-decoration:line-through; color:#bbb; font-size:0.98em; margin-right:8px;">${ev.price.before.toLocaleString()}원</span> ${ev.price.after.toLocaleString()}원 부터`;
const link = document.createElement('a');
link.className = 'event-link';
link.href = ev.link;
link.textContent = '자세히 보기';
info.appendChild(title);
info.appendChild(desc);
if(ev.meta) info.appendChild(meta);
info.appendChild(price);
info.appendChild(link);
card.appendChild(imgBox);
card.appendChild(info);
list.appendChild(card);
});
}
renderEvents();
// 사이드바 메뉴 클릭 효과
document.querySelectorAll('.sidebar .menu-list button').forEach(btn => {
btn.addEventListener('click', function() {
document.querySelectorAll('.sidebar .menu-list button').forEach(b => b.classList.remove('active'));
this.classList.add('active');
// 실제 서비스에서는 이곳에서 해당 카테고리별 이벤트 목록을 불러오는 로직을 추가
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,301 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>피부과 전후사진 게시판</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
:root {
--main-bg: #f6f7fb;
--card-bg: #fff;
--accent: #b23c3c;
--text: #222;
--muted: #888;
--shadow: 0 2px 12px rgba(0,0,0,0.07);
--radius: 18px;
}
* { box-sizing: border-box; }
body {
margin: 0;
font-family: 'Noto Sans KR', sans-serif;
background: var(--main-bg);
color: var(--text);
min-height: 100vh;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 16px 40px 16px;
display: flex;
gap: 32px;
align-items: flex-start;
}
.sidebar {
width: 220px;
background: var(--card-bg);
border-radius: var(--radius);
box-shadow: var(--shadow);
padding: 24px 16px;
min-width: 160px;
margin-top: 32px;
}
.sidebar-title {
font-weight: 700;
color: var(--accent);
margin-bottom: 16px;
font-size: 1.1em;
}
.category-list {
list-style: none;
padding: 0;
margin: 0;
}
.category-list li {
margin-bottom: 10px;
}
.category-btn {
width: 100%;
background: none;
border: none;
text-align: left;
padding: 8px 0;
font-size: 1em;
color: var(--text);
cursor: pointer;
border-radius: 8px;
transition: background 0.13s, color 0.13s;
}
.category-btn.active,
.category-btn:hover {
background: #f5eaea;
color: var(--accent);
font-weight: 600;
}
.main-content {
flex: 1 1 0;
min-width: 260px;
margin-top: 32px;
}
.board-title {
font-size: 1.6em;
font-weight: 700;
margin-bottom: 18px;
color: var(--accent);
}
.photo-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
gap: 28px;
}
.photo-card {
background: var(--card-bg);
border-radius: var(--radius);
box-shadow: var(--shadow);
overflow: hidden;
transition: box-shadow 0.17s;
display: flex;
flex-direction: column;
}
.photo-card:hover {
box-shadow: 0 6px 24px rgba(178,60,60,0.14);
}
.photo-images {
display: flex;
gap: 0;
background: #f1f1f4;
border-bottom: 1px solid #f2f2f2;
transition: background 0.2s;
}
.photo-img-box {
flex: 1 1 0;
position: relative;
aspect-ratio: 1.2/1;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.photo-img-box img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s;
}
.photo-card:hover .photo-img-box img {
transform: scale(1.05);
}
.photo-label {
position: absolute;
left: 10px; top: 10px;
background: rgba(0,0,0,0.5);
color: #fff;
font-size: 0.93em;
padding: 3px 11px;
border-radius: 12px;
letter-spacing: 0.03em;
}
.photo-info {
padding: 18px 20px 14px 20px;
display: flex;
flex-direction: column;
gap: 7px;
}
.photo-title {
font-size: 1.18em;
font-weight: 700;
margin-bottom: 2px;
color: var(--text);
}
.photo-desc {
color: var(--muted);
font-size: 1em;
line-height: 1.5;
}
@media (max-width: 900px) {
.container { flex-direction: column; gap: 18px; }
.sidebar { width: 100%; min-width: unset; margin-top: 0; }
.main-content { margin-top: 0; }
}
@media (max-width: 600px) {
.container { padding: 0 2vw 24px 2vw; }
.sidebar { padding: 14px 6px; border-radius: 10px; }
.photo-card { border-radius: 10px; }
.photo-info { padding: 12px 8px 10px 10px; }
.photo-grid { gap: 14px; }
.photo-images { flex-direction: column; }
.photo-img-box { aspect-ratio: 1.1/1; }
.photo-label { left: 8px; top: 8px; font-size: 0.89em; }
}
</style>
</head>
<body>
<div class="container">
<!-- Sidebar -->
<aside class="sidebar">
<div class="sidebar-title">카테고리</div>
<ul class="category-list" id="category-list">
<li><button class="category-btn active" data-category="전체">전체</button></li>
<li><button class="category-btn" data-category="여드름">여드름</button></li>
<li><button class="category-btn" data-category="잡티/색소">잡티/색소</button></li>
<li><button class="category-btn" data-category="리프팅">리프팅</button></li>
<li><button class="category-btn" data-category="흉터">흉터</button></li>
<li><button class="category-btn" data-category="모공">모공</button></li>
</ul>
</aside>
<!-- Main Content -->
<main class="main-content">
<div class="board-title">전후사진 게시판</div>
<div class="photo-grid" id="photo-grid">
<!-- JS로 게시물 렌더링 -->
</div>
</main>
</div>
<script>
// 샘플 데이터
const posts = [
{
category: "여드름",
title: "여드름 치료 4주차",
desc: "붉은 여드름과 염증 완화, 피부결 개선 효과.",
before: "https://images.unsplash.com/photo-1518717758536-85ae29035b6d?auto=format&fit=facearea&w=400&h=250",
after: "https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=facearea&w=400&h=250"
},
{
category: "잡티/색소",
title: "색소침착 개선",
desc: "기미, 잡티, 색소침착이 옅어지고 맑아진 피부.",
before: "https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=facearea&w=400&h=250",
after: "https://images.unsplash.com/photo-1517841905240-472988babdf9?auto=format&fit=facearea&w=400&h=250"
},
{
category: "리프팅",
title: "리프팅 시술 2회 후",
desc: "처진 턱선과 볼살이 또렷하게 개선됨.",
before: "https://images.unsplash.com/photo-1454023492550-5696f8ff10e1?auto=format&fit=facearea&w=400&h=250",
after: "https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=facearea&w=400&h=250"
},
{
category: "흉터",
title: "여드름 흉터 치료",
desc: "깊은 흉터가 완화되고 피부결이 매끄러워짐.",
before: "https://images.unsplash.com/photo-1465101178521-c1a9136a3c8b?auto=format&fit=facearea&w=400&h=250",
after: "https://images.unsplash.com/photo-1518715308788-3005759c61e9?auto=format&fit=facearea&w=400&h=250"
},
{
category: "모공",
title: "모공 축소 3회차",
desc: "넓은 모공이 눈에 띄게 줄어든 모습.",
before: "https://images.unsplash.com/photo-1465101178521-c1a9136a3c8b?auto=format&fit=facearea&w=400&h=250",
after: "https://images.unsplash.com/photo-1518715308788-3005759c61e9?auto=format&fit=facearea&w=400&h=250"
}
];
// 게시물 렌더링 함수
function renderPosts(category = "전체") {
const grid = document.getElementById('photo-grid');
grid.innerHTML = '';
const filtered = category === "전체" ? posts : posts.filter(p => p.category === category);
filtered.forEach(post => {
const card = document.createElement('div');
card.className = 'photo-card';
const images = document.createElement('div');
images.className = 'photo-images';
const beforeBox = document.createElement('div');
beforeBox.className = 'photo-img-box';
const beforeImg = document.createElement('img');
beforeImg.src = post.before;
beforeImg.alt = post.title + ' - Before';
const beforeLabel = document.createElement('div');
beforeLabel.className = 'photo-label';
beforeLabel.textContent = 'Before';
beforeBox.appendChild(beforeImg);
beforeBox.appendChild(beforeLabel);
const afterBox = document.createElement('div');
afterBox.className = 'photo-img-box';
const afterImg = document.createElement('img');
afterImg.src = post.after;
afterImg.alt = post.title + ' - After';
const afterLabel = document.createElement('div');
afterLabel.className = 'photo-label';
afterLabel.textContent = 'After';
afterBox.appendChild(afterImg);
afterBox.appendChild(afterLabel);
images.appendChild(beforeBox);
images.appendChild(afterBox);
const info = document.createElement('div');
info.className = 'photo-info';
const title = document.createElement('div');
title.className = 'photo-title';
title.textContent = post.title;
const desc = document.createElement('div');
desc.className = 'photo-desc';
desc.textContent = post.desc;
info.appendChild(title);
info.appendChild(desc);
card.appendChild(images);
card.appendChild(info);
grid.appendChild(card);
});
}
renderPosts();
// 카테고리 필터
document.querySelectorAll('.category-btn').forEach(btn => {
btn.addEventListener('click', function() {
document.querySelectorAll('.category-btn').forEach(b => b.classList.remove('active'));
this.classList.add('active');
renderPosts(this.dataset.category);
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,259 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>전후사진 상세페이지</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
:root {
--main-bg: #f6f7fb;
--card-bg: #fff;
--accent: #b23c3c;
--text: #222;
--muted: #888;
--shadow: 0 2px 12px rgba(0,0,0,0.07);
--radius: 18px;
}
* { box-sizing: border-box; }
body {
margin: 0;
font-family: 'Noto Sans KR', sans-serif;
background: var(--main-bg);
color: var(--text);
min-height: 100vh;
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 0 16px 40px 16px;
}
.detail-card {
background: var(--card-bg);
border-radius: var(--radius);
box-shadow: var(--shadow);
margin-top: 40px;
display: flex;
gap: 36px;
padding: 36px 32px;
align-items: flex-start;
flex-wrap: wrap;
transition: box-shadow 0.17s;
}
.detail-card:hover {
box-shadow: 0 6px 24px rgba(178,60,60,0.14);
}
.photo-section {
flex: 0 0 340px;
min-width: 260px;
display: flex;
flex-direction: column;
align-items: center;
gap: 22px;
}
.compare-slider {
position: relative;
width: 320px;
max-width: 100%;
aspect-ratio: 1.2/1;
border-radius: 14px;
overflow: hidden;
box-shadow: 0 1px 8px rgba(0,0,0,0.06);
background: #f1f1f4;
margin-bottom: 6px;
user-select: none;
touch-action: none;
}
.compare-slider img {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
object-fit: cover;
transition: filter 0.2s;
}
.compare-slider .after-img {
clip-path: inset(0 0 0 50%);
z-index: 2;
transition: clip-path 0.2s;
}
.compare-slider .before-img {
z-index: 1;
}
.compare-slider .slider-bar {
position: absolute;
top: 0; left: 50%;
width: 3px; height: 100%;
background: var(--accent);
z-index: 3;
cursor: ew-resize;
transition: background 0.2s;
border-radius: 2px;
box-shadow: 0 0 4px rgba(178,60,60,0.15);
}
.compare-slider .slider-dot {
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
width: 28px; height: 28px;
background: var(--accent);
border-radius: 50%;
border: 3px solid #fff;
box-shadow: 0 2px 10px rgba(178,60,60,0.10);
z-index: 4;
cursor: ew-resize;
display: flex; align-items: center; justify-content: center;
color: #fff; font-size: 1.2em;
}
.compare-labels {
display: flex;
justify-content: space-between;
width: 100%;
margin-top: 6px;
font-size: 0.99em;
color: #fff;
font-weight: 600;
letter-spacing: 0.03em;
}
.compare-labels span {
background: rgba(0,0,0,0.5);
padding: 3px 14px;
border-radius: 12px;
}
.info-section {
flex: 1 1 320px;
min-width: 220px;
display: flex;
flex-direction: column;
gap: 18px;
}
.detail-title {
font-size: 1.45em;
font-weight: 700;
color: var(--accent);
margin-bottom: 4px;
}
.detail-desc {
color: var(--text);
font-size: 1.05em;
line-height: 1.6;
margin-bottom: 6px;
}
.detail-meta {
color: var(--muted);
font-size: 0.98em;
margin-bottom: 10px;
}
.tag-list {
display: flex;
flex-wrap: wrap;
gap: 7px;
margin-bottom: 10px;
}
.tag {
background: #f5eaea;
color: var(--accent);
font-size: 0.97em;
border-radius: 10px;
padding: 4px 14px;
font-weight: 500;
}
.back-link {
display: inline-block;
margin-top: 18px;
color: var(--accent);
font-weight: 600;
text-decoration: none;
border-bottom: 1.5px solid #b23c3c33;
font-size: 1em;
transition: color 0.13s;
}
.back-link:hover { color: #a12f2f; }
@media (max-width: 900px) {
.detail-card { flex-direction: column; gap: 18px; padding: 22px 10px; }
.photo-section { align-items: stretch; }
.compare-slider { width: 100%; }
}
@media (max-width: 600px) {
.container { padding: 0 2vw 24px 2vw; }
.detail-card { border-radius: 10px; }
.compare-slider { border-radius: 8px; }
.info-section { padding: 0 2px; }
}
</style>
</head>
<body>
<div class="container">
<div class="detail-card">
<!-- 이미지 비교 영역 -->
<section class="photo-section">
<div class="compare-slider" id="compare-slider">
<img src="https://images.unsplash.com/photo-1518717758536-85ae29035b6d?auto=format&fit=facearea&w=600&h=400" alt="여드름 치료 전" class="before-img">
<img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=facearea&w=600&h=400" alt="여드름 치료 후" class="after-img">
<div class="slider-bar"></div>
<div class="slider-dot">&#8596;</div>
</div>
<div class="compare-labels">
<span>Before</span>
<span>After</span>
</div>
</section>
<!-- 상세 정보 영역 -->
<section class="info-section">
<div class="detail-title">여드름 치료 4주차</div>
<div class="detail-meta">카테고리: 여드름 &nbsp;|&nbsp; 등록일: 2025-07-12</div>
<div class="tag-list">
<span class="tag">#여드름</span>
<span class="tag">#피부개선</span>
<span class="tag">#4주차</span>
</div>
<div class="detail-desc">
붉은 여드름과 염증이 4주간의 치료 후 눈에 띄게 완화되었습니다.<br>
피부결이 매끄러워지고, 자극 없이 자연스럽게 개선된 사례입니다.
</div>
<div class="detail-desc" style="color:#b23c3c; font-weight:500;">
※ 시술 결과는 개인에 따라 다를 수 있습니다.
</div>
<a href="#" class="back-link" onclick="history.back();return false;">목록으로 돌아가기</a>
</section>
</div>
</div>
<script>
// Before-After 슬라이더 기능 (모바일/PC 모두 지원)
const slider = document.getElementById('compare-slider');
const afterImg = slider.querySelector('.after-img');
const bar = slider.querySelector('.slider-bar');
const dot = slider.querySelector('.slider-dot');
let dragging = false;
function setSlider(x) {
const rect = slider.getBoundingClientRect();
let pos = Math.max(0, Math.min(x - rect.left, rect.width));
let percent = pos / rect.width * 100;
afterImg.style.clipPath = `inset(0 0 0 ${percent}%)`;
bar.style.left = percent + '%';
dot.style.left = percent + '%';
}
function startDrag(e) {
dragging = true;
document.body.style.userSelect = 'none';
}
function stopDrag() {
dragging = false;
document.body.style.userSelect = '';
}
function onDrag(e) {
if (!dragging) return;
let x = e.touches ? e.touches[0].clientX : e.clientX;
setSlider(x);
}
slider.addEventListener('mousedown', startDrag);
slider.addEventListener('touchstart', startDrag);
window.addEventListener('mousemove', onDrag);
window.addEventListener('touchmove', onDrag);
window.addEventListener('mouseup', stopDrag);
window.addEventListener('touchend', stopDrag);
// 초기값 중앙
setSlider(slider.getBoundingClientRect().width / 2 + slider.getBoundingClientRect().left);
</script>
</body>
</html>

View File

@@ -0,0 +1,121 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/accept/webAccept.css?ver=2">
</th:block>
<th:block layout:fragment="layoutContent">
<main>
<section class="privacy-policy">
<header>
<h2>📄 메이드유의원 개인정보처리방침</h2>
<p>메이드유의원(이하 "의원"이라 함)은 「개인정보 보호법」 등 관련 법령에 따라 이용자의 개인정보를 보호하고, 이와 관련한 고충을 신속하고 원활하게 처리할 수 있도록 다음과 같은 개인정보처리방침을 수립·공개합니다.</p>
</header>
<hr>
<section>
<h3>제1조 (개인정보의 수집 항목 및 수집 방법)</h3>
<ol>
<li><strong>수집 항목</strong>
<ul>
<li>필수항목: 이름, 이메일, 전화번호, 주소</li>
</ul>
</li>
<li><strong>수집 방법</strong>
<ul>
<li>홈페이지 회원가입, 고객문의, 상담 신청 등을 통해 수집됩니다.</li>
</ul>
</li>
</ol>
</section>
<hr>
<section>
<h3>제2조 (개인정보의 수집 및 이용 목적)</h3>
<ul>
<li>홈페이지 회원관리 및 서비스 제공</li>
<li>고객문의 및 상담 응대</li>
<li>이벤트, 마케팅 및 광고 활용</li>
</ul>
</section>
<hr>
<section>
<h3>제3조 (개인정보의 보유 및 이용 기간)</h3>
<ul>
<li><strong>회원정보</strong>: 회원 탈퇴 시까지 보유</li>
<li><strong>관련 법령에 따른 보존</strong>: 전자상거래 등에서의 소비자 보호에 관한 법률 등 관계법령에서 정한 기간</li>
</ul>
<p>의원은 수집한 개인정보를 원칙적으로 개인정보의 수집 및 이용 목적이 달성된 후에는 지체 없이 파기합니다. 단, 관련 법령에 따라 일정 기간 보존이 필요한 경우에는 해당 기간 동안 보관합니다.</p>
</section>
<hr>
<section>
<h3>제4조 (개인정보의 제3자 제공)</h3>
<ul>
<li>이용자의 사전 동의를 받은 경우</li>
<li>법령의 규정에 의거하거나, 수사 목적으로 법령에 정해진 절차와 방법에 따라 수사기관의 요구가 있는 경우</li>
</ul>
<table class="info-table">
<tr><th>제공 대상</th><td>(주)리라로</td></tr>
<tr><th>제공 목적</th><td>마케팅 및 이벤트 안내</td></tr>
<tr><th>제공 항목</th><td>이름, 전화번호, 이메일 등</td></tr>
<tr><th>보유 및 이용 기간</th><td>제공 목적 달성 시까지</td></tr>
</table>
</section>
<hr>
<section>
<h3>제5조 (개인정보의 처리 위탁)</h3>
<p>의원은 현재 개인정보 처리를 외부 업체에 <strong>위탁하고 있지 않습니다.</strong></p>
</section>
<hr>
<section>
<h3>제6조 (정보주체의 권리와 행사방법)</h3>
<ul>
<li>개인정보 열람요구</li>
<li>오류 등이 있을 경우 정정요구</li>
<li>삭제요구</li>
<li>처리정지 요구</li>
</ul>
<p>권리 행사는 이메일(<a href="mailto:gol1980@lilaloglobal.com">gol1980@lilaloglobal.com</a>)을 통해 요청하실 수 있으며, 의원은 이에 대해 지체 없이 조치하겠습니다.</p>
</section>
<hr>
<section>
<h3>제7조 (개인정보의 파기 절차 및 방법)</h3>
<ul>
<li><strong>파기절차</strong>: 목적 달성 후 별도 DB로 옮겨져 내부 방침 및 관련 법령에 따라 일정 기간 저장 후 파기</li>
<li><strong>파기방법</strong>: 전자적 파일은 복구 불가능한 방법으로 영구 삭제, 종이 문서는 분쇄기로 파기</li>
</ul>
</section>
<hr>
<section>
<h3>제8조 (개인정보의 안전성 확보조치)</h3>
<ul>
<li>개인정보의 암호화</li>
<li>해킹 등에 대비한 기술적 대책</li>
<li>접근통제 및 권한 관리</li>
<li>개인정보 처리 직원의 최소화 및 교육</li>
</ul>
</section>
<hr>
<section>
<h3>제9조 (개인정보 보호책임자)</h3>
<ul>
<li><strong>개인정보 보호책임자</strong>: 메이드유의원</li>
<li><strong>이메일</strong>: <a href="mailto:gol1980@lilaloglobal.com">gol1980@lilaloglobal.com</a></li>
</ul>
</section>
<hr>
<section>
<h3>제10조 (개인정보처리방침의 변경)</h3>
<ul>
<li>이 개인정보처리방침은 법령, 정책 또는 의원 내부 방침에 따라 변경될 수 있으며, 개정 시 홈페이지를 통해 사전 공지합니다.</li>
<li><strong>공고일자</strong>: 2025년 9월 5일</li>
<li><strong>시행일자</strong>: 2025년 9월 12일</li>
</ul>
</section>
</section>
</main>
</th:block>
<th:block layout:fragment="layoutContentScript">
<script src="/js/web/accept/webAccept.js?ver=2"></script>
</th:block>
</html>

View File

@@ -0,0 +1,136 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/accept/webAccept.css?ver=2">
</th:block>
<th:block layout:fragment="layoutContent">
<main>
<section class="terms-policy">
<header>
<h2>📄 메이드유의원 홈페이지 이용약관</h2>
<p>본 이용약관은 메이드유의원(이하 "의원")이 운영하는 웹사이트(이하 "사이트")의 이용과 관련하여, 이용자와 의원 간의 권리, 의무 및 책임사항, 기타 필요한 사항을 규정함을 목적으로 합니다.</p>
</header>
<hr>
<section>
<h3>제1조 (목적)</h3>
<p>이 약관은 의원이 제공하는 인터넷 관련 서비스(이하 "서비스")의 이용 조건 및 절차, 이용자와 의원의 권리·의무 및 책임사항 등을 규정함을 목적으로 합니다.</p>
</section>
<hr>
<section>
<h3>제2조 (정의)</h3>
<ol>
<li><strong>사이트</strong>: 메이드유의원이 운영하는 웹사이트를 의미합니다.</li>
<li><strong>이용자</strong>: 사이트에 접속하여 이 약관에 따라 서비스를 이용하는 자를 말합니다.</li>
<li><strong>회원</strong>: 사이트에 개인정보를 제공하여 회원등록을 한 자로서, 지속적으로 의원이 제공하는 정보를 이용할 수 있는 자를 말합니다.</li>
<li><strong>비회원</strong>: 회원가입을 하지 않고 서비스를 이용하는 자를 말합니다.</li>
</ol>
</section>
<hr>
<section>
<h3>제3조 (약관의 효력 및 변경)</h3>
<ol>
<li>본 약관은 사이트에 게시하거나 기타의 방법으로 이용자에게 공지함으로써 효력을 발생합니다.</li>
<li>의원은 관련 법령을 위반하지 않는 범위 내에서 약관을 개정할 수 있으며, 개정된 약관은 적용일자 및 개정사유와 함께 사이트에 공지합니다.</li>
<li>이용자가 변경된 약관에 동의하지 않을 경우, 회원탈퇴를 요청할 수 있으며, 변경 약관의 효력 발생일 이후에도 서비스를 계속 이용할 경우 약관에 동의한 것으로 간주합니다.</li>
</ol>
</section>
<hr>
<section>
<h3>제4조 (서비스의 제공 및 변경)</h3>
<ol>
<li>의원은 다음과 같은 서비스를 제공합니다.
<ul>
<li>홈페이지를 통한 병원 정보 제공</li>
<li>온라인 문의 및 상담</li>
<li>이벤트 및 프로모션 안내</li>
<li>기타 의원이 정하는 서비스</li>
</ul>
</li>
<li>의원은 서비스의 내용, 운영상 또는 기술상 필요에 따라 변경할 수 있습니다. 이 경우 변경된 내용을 사전에 공지합니다.</li>
</ol>
</section>
<hr>
<section>
<h3>제5조 (서비스의 중단)</h3>
<ol>
<li>의원은 다음의 경우 서비스 제공을 일시적으로 중단할 수 있습니다.
<ul>
<li>시스템 점검, 유지보수 등 필요한 경우</li>
<li>정전, 서버 장애, 시스템 다운 등 불가항력적 사유가 발생한 경우</li>
<li>기타 운영상 상당한 이유가 있는 경우</li>
</ul>
</li>
<li>서비스 중단 시 사전에 공지하며, 부득이한 경우 사후에 공지할 수 있습니다.</li>
</ol>
</section>
<hr>
<section>
<h3>제6조 (회원가입 및 관리)</h3>
<ol>
<li>이용자는 의원이 정한 가입 양식에 따라 회원정보를 기입하여 회원가입을 신청합니다.</li>
<li>의원은 신청자에게 서비스 이용을 허락함으로써 회원가입이 완료됩니다.</li>
<li>회원은 등록한 정보에 변경이 있을 경우, 즉시 수정해야 하며, 수정하지 않아 발생한 불이익에 대해서는 의원이 책임지지 않습니다.</li>
</ol>
</section>
<hr>
<section>
<h3>제7조 (이용자의 의무)</h3>
<ul>
<li>타인의 정보를 도용하거나 허위 정보를 입력하는 행위</li>
<li>사이트 운영을 방해하거나 장애를 유발하는 행위</li>
<li>저작권 등 타인의 권리를 침해하는 행위</li>
<li>공공질서 및 미풍양속에 반하는 행위</li>
<li>관련 법령 또는 본 약관을 위반하는 행위</li>
</ul>
</section>
<hr>
<section>
<h3>제8조 (의원의 의무)</h3>
<ol>
<li>의원은 관련 법령과 본 약관이 금지하거나 미풍양속에 반하는 행위를 하지 않으며, 지속적이고 안정적으로 서비스를 제공하기 위해 최선을 다합니다.</li>
<li>의원은 이용자의 개인정보 보호를 위해 개인정보처리방침을 수립하고 준수합니다.</li>
</ol>
</section>
<hr>
<section>
<h3>제9조 (저작권의 귀속 및 이용 제한)</h3>
<ol>
<li>사이트에 게시된 모든 콘텐츠(텍스트, 이미지 등)의 저작권은 의원 또는 정당한 권리자에게 있으며, 무단 복제, 배포, 전송, 변형 등을 금합니다.</li>
<li>이용자는 서비스를 이용함으로써 얻은 정보를 의원의 사전 승인 없이 복제, 유통, 상업적 이용할 수 없습니다.</li>
</ol>
</section>
<hr>
<section>
<h3>제10조 (면책 조항)</h3>
<ol>
<li>의원은 천재지변, 시스템 오류 등 불가항력적 사유로 인해 서비스를 제공할 수 없는 경우 책임을 지지 않습니다.</li>
<li>의원은 이용자의 귀책사유로 인한 서비스 이용 장애에 대하여 책임을 지지 않습니다.</li>
<li>의원은 이용자가 사이트에 게재한 정보, 자료, 사실의 신뢰도 및 정확성에 대하여 책임을 지지 않습니다.</li>
</ol>
</section>
<hr>
<section>
<h3>제11조 (분쟁 해결 및 관할법원)</h3>
<ol>
<li>서비스 이용과 관련하여 의원과 이용자 사이에 분쟁이 발생한 경우, 원만한 해결을 위해 상호 협의합니다.</li>
<li>협의가 이루어지지 않을 경우, 민사소송법상의 관할법원에 소를 제기할 수 있습니다.</li>
</ol>
</section>
<hr>
<section>
<h3>부칙</h3>
<ul>
<li>본 약관은 2025년 9월 12일부터 시행합니다.</li>
<li>본 약관에 명시되지 않은 사항은 관계 법령 및 상관례에 따릅니다.</li>
</ul>
</section>
</section>
</main>
</th:block>
<th:block layout:fragment="layoutContentScript">
<script src="/js/web/accept/webAccept.js?ver=2"></script>
</th:block>
</html>

View File

@@ -0,0 +1,189 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/diet/dietInjectionSelect.css?v1.0">
</th:block>
<th:block layout:fragment="layoutContent">
<div class="same">
<aside>
<ul>
<li class="first"><a href="#v">메쉬다 V</a></li>
<li><a href="#s">메쉬다 S</a></li>
</ul>
</aside>
<main>
<section class="main_img">
<img class="pc" src="/image/web/diet_main.jpg" alt="diet"/>
<img class="mb" src="/image/web/Mdiet_main.jpg" alt="diet"/>
<div class="text_box">
<div class="left_text_box">
<p class="sub_title">메이드유<span> 쉬운 다이어트 주사 메쉬다 S / V</span></p>
<p class="title">Unique <span>Solution</span></p>
<p class="sub_text">아름다움 극대화를 위해<br/><span>끊임없이 연구하고 노력합니다.</span></p>
</div>
<div class="right_text_box"><p><span>V </span>Line</p></div>
</div>
</section>
<section class="content1">
<div class="inner_wrap">
<p class="title">다이어트 주사 - 메쉬다 V, S</p>
<p class="sub_title">메쉬다는 얼굴 메쉬다V와 바디 메쉬다S로 구분</p>
<p class="sub_text">
메쉬다S는 오랜임상을 거쳐 만든 독자적인 메이드유만의 바디 지방파괴 및 감소 효과를 보이며 <br/>
말랑말랑 바디 지방 + 탱탱 바디 지방을 동시에 해결하는 주사로 3~5회를 추천드립니다.
</p>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<h3><span>시술효과 </span>Effect</h3>
<ul>
<li><p>1회시술만으로도<br/>효과UP</p></li>
<li><p>지방 세포<br/>분해</p></li>
<li><p>림프순환촉진<br/>UP으로<br/>붓기최소화</p></li>
<li><p>바디 탄력<br/>효과</p></li>
</ul>
</div>
</section>
<section class="content3">
<div class="inner_wrap">
<h3><span>특징 </span>Unique</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>PPC NO! 붓기가 일어날 수 있는 PPC성분이 없습니다.</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>메이드유만의 독자적인 단계별 다이어트약 병행</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>효과 Double UP! 독자적인 노하우로 효과가 큽니다.</p>
</li>
</ul>
</div>
</section>
<section class="content4">
<div class="inner_wrap">
<h3><span>시술횟수 </span>Time</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/time.png" alt="check"/></div>
<p>1주 간격으로 5~10회</p>
</li>
</ul>
</div>
</section>
<section class="content5">
<div class="inner_wrap">
<h3><span>주의사항 </span>Notice</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/notice.png" alt="check"/></div>
<p>
개인의 특성에 따라 붓기가 생길수 있습니다.<br/>
시술 부위를 누르거나 문지르는 등의 강한 자극은 피해주셔야 합니다<br/>
시술 후 일주일 동안은 흡연, 음주를 삼갑니다.
</p>
</li>
</ul>
</div>
</section>
<div id="v">
<section class="content6 img_cont">
<div class="inner_wrap">
<p>
수술없이 티안나게 나타나는 V라인<br/>
<span>MADE U 메쉬다 V주사</span>
</p>
<ul>
<li>
<img src="/image/web/cont6_1.jpg" alt="cont6_1"/>
<div class="text_box">
<p class="sub_title">Facial contouring improvement</p>
<p class="title">얼굴 윤곽 개선</p>
<p class="sub_text">접히고 튀어나온 턱선을 매끈하고<br/> 갸름하게 만들어 또렷한 인상으로!</p>
</div>
</li>
<li>
<img src="/image/web/cont6_2.jpg" alt="cont6_2"/>
<div class="text_box">
<p class="sub_title">Skin tone enhancement</p>
<p class="title">안색 개선</p>
<p class="sub_text">메쉬다 V주사는 조각난 지방과 <br/>노폐물 배출로, 안색 개선을 도움!</p>
</div>
</li>
<li>
<img src="/image/web/cont6_3.jpg" alt="cont6_3"/>
<div class="text_box">
<p class="sub_title">Facial asymmetry correction</p>
<p class="title">안면 비대칭 개선</p>
<p class="sub_text">한쪽으로 치우친 턱 라인을 균형잡아 <br/>예쁜 브이라인을 만듭니다.</p>
</div>
</li>
<li>
<img src="/image/web/cont6_4.jpg" alt="cont6_4"/>
<div class="text_box">
<p class="sub_title">Facial slimming</p>
<p class="title">얼굴 축소</p>
<p class="sub_text">턱 밑에 자리잡은 지방 제거로, <br/>얼굴이 작아지는 효과!</p>
</div>
</li>
</ul>
</div>
</section>
</div>
<div id="s">
<section class="content7 img_cont">
<div class="inner_wrap">
<p>
메이드유 지방분해주사 특징은?<br/>
<span>MADE U 메쉬다 S주사</span>
</p>
<ul>
<li>
<img src="/image/web/cont7_1.jpg" alt="cont6_1"/>
<div class="text_box">
<p class="sub_title">Detail 01</p>
<p class="title">복부 둘레감소</p>
<p class="sub_text">복부의 잘 빠지지 않는 지방세포<br/>자체를 분해하여 복부 둘레를 감소!</p>
</div>
</li>
<li>
<img src="/image/web/cont7_2.jpg" alt="cont7_2"/>
<div class="text_box">
<p class="sub_title">Detail 02</p>
<p class="title">복부라인 개선</p>
<p class="sub_text">아랫배, 러브핸들 부위의 군살, <br/>셀룰라이트를 제거, 슬림한 S라인!</p>
</div>
</li>
<li>
<img src="/image/web/cont7_3.jpg" alt="cont7_3"/>
<div class="text_box">
<p class="sub_title">Detail 03</p>
<p class="title">허벅지 안쪽라인 개선</p>
<p class="sub_text">축적된 허벅지 안쪽 지방을 제거,<br/>허벅지 사이에 충분한 틈을 생성!</p>
</div>
</li>
<li>
<img src="/image/web/cont7_4.jpg" alt="cont7_4"/>
<div class="text_box">
<p class="sub_title">Detail 04</p>
<p class="title">종아리 부종 개선</p>
<p class="sub_text">종아리에 쌓인 부종을 제거하여<br/>매끈한 라인으로 개선합니다.</p>
</div>
</li>
</ul>
</div>
</section>
</div>
</main>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
</th:block>
</html>

View File

@@ -0,0 +1,196 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/diet/dietLaserSelect.css?v1.0">
</th:block>
<th:block layout:fragment="layoutContent">
<div class="same">
<aside>
<ul>
<li class="first"><a href="#ulfit">울핏</a></li>
<li><a href="#tunebody">튠바디</a></li>
</ul>
</aside>
<main>
<!-- 울핏 -->
<div id="ulfit">
<section class="main_img">
<img class="pc" src="/image/web/diet_main3_1.jpg" alt="diet"/>
<img class="mb" src="/image/web/Mdiet_main3_1.jpg" alt="diet"/>
<div class="text_box">
<div class="left_text_box">
<p class="sub_title">바디를 탄력있고 아름답게 관리!</p>
<p class="title">울핏 Ulfit</p>
<p class="sub_text">
넓은 부위도 균일하고 빠르게! <br/>
바디 (복부 및 허벅지) 탄력개선 HIFU 장비
</p>
</div>
</div>
</section>
<section class="content1">
<div class="inner_wrap">
<p class="title">울핏 Ulfit</p>
<p class="sub_title">울핏은 강한 초음파 에너지 (HIFU)를 이용하여 탄력있는 바디를 위한 핏을 만드는 시술!</p>
<p class="sub_text">
강한 초음파 에너지 (HIFU)를 피하지방층에 집속하여 빠른 시술 효과로 탄력있고 매력적인 몸매를 만들어줍니다. <br/>
울핏 바디 타이트닝은 비침습적 방식으로 고질적인 지방 세포를 재배치하여 바디타이트닝에 효과적입니다. <br/>
고강도 집속 초음파를 이용하여 비침습적 시술이 가능하며 시술 후 빠른 일상생활이 가능합니다.
</p>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<h3><span>시술효과 </span>Effect</h3>
<ul>
<li><p>늘어지고 <br/>처진피부의 개선</p></li>
<li><p>탄력있는 <br/>바디 타이트닝</p></li>
<li><p>원하는 부위의 <br/>지방제거 <br/>운동만으로 부족한 <br/>체형 개선</p></li>
<li><p>2번 당겨주는 <br/>2단계 리프팅 효과</p></li>
</ul>
</div>
</section>
<section class="content3">
<div class="inner_wrap">
<h3><span>특징 </span>Unique</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>2단계 탄력 바디 개선으로 편안합니다. </p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>식약처가 허가한 비침습 방식의 안전한 시술입니다.</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>원하는 부위 시술이 가능, 늘어지고 처진 몸매에 탄력을!</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>시술 후 일상생활을 하는데 지장이 없습니다.</p>
</li>
</ul>
</div>
</section>
<section class="content4">
<div class="inner_wrap">
<h3><span>시술횟수 </span>Time</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/time.png" alt="check"/></div>
<p>체형 분석후 의료진의 처방에 따라</p>
</li>
</ul>
</div>
</section>
<section class="content5">
<div class="inner_wrap">
<h3><span>주의사항 </span>Notice</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/notice.png" alt="check"/></div>
<p>
통증과 부작용은 거의 없음<br/>
일시적으로 멍이 발생할수 있으나 자연스럽게 사라짐
</p>
</li>
</ul>
</div>
</section>
</div>
<!-- 튠바디 -->
<div id="tunebody">
<section class="main_img">
<img class="pc" src="/image/web/diet_main3_2.jpg" alt="diet"/>
<img class="mb" src="/image/web/Mdiet_main3_2.jpg" alt="diet"/>
<div class="text_box">
<div class="left_text_box">
<p class="sub_title">잃어버린 바디라인을 되찾다!</p>
<p class="title">튠바디</p>
<p class="sub_text">
튠은 시술 깊이를 조절하는 <br/>
선택적 치료기술을 통해 환자 개인에 맞는 <br/>
맞춤형 치료를 제공할 수 있습니다.
</p>
</div>
</div>
</section>
<section class="content1">
<div class="inner_wrap">
<p class="title">튠바디</p>
<p class="sub_title">지방세포막 파괴 효과! 튼살부터 셀룰라이트까지</p>
<p class="sub_text">
통증 없이 선택적으로 파괴하는 3D 입체초음파 레이저 지방분해시술
</p>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<h3><span>시술효과 </span>Effect</h3>
<ul>
<li><p>요요 현상 없이 <br/>오래도록 <br/>지속되는 바디 시술</p></li>
<li><p>팔뚝, 복부, 옆구리, <br/>종아리, 허벅지 등 <br/>바디 시술 가능</p></li>
<li><p>적은 통증과 <br/>자극으로 <br/>20분내에 완성되는 <br/>효과적인 시술</p></li>
<li><p>모든 부위에 <br/>시술 가능</p></li>
</ul>
</div>
</section>
<section class="content3">
<div class="inner_wrap">
<h3><span>특징 </span>Unique</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>3D 입체 초음파 웨이브가 지방세포만을 파괴합니다.</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>지방세포막을 자극하고 파괴해 효과적인 비만치료가 가능!</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>원하는 부위 시술이 가능, 늘어지고 처진 몸매에 탄력을!</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>통증과 자극 최소화하고 20분만에 완성되는 시술입니다.</p>
</li>
</ul>
</div>
</section>
<section class="content4">
<div class="inner_wrap">
<h3><span>시술횟수 </span>Time</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/time.png" alt="check"/></div>
<p>체형 분석후 의료진의 처방에 따라</p>
</li>
</ul>
</div>
</section>
<section class="content5">
<div class="inner_wrap">
<h3><span>주의사항 </span>Notice</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/notice.png" alt="check"/></div>
<p>
바세린 알레르기가 있는 분은 시술 받기 어렵습니다.<br/>
시술 후 붉은기, 피부 특성에 따라 30분에서 1일 정도 지속
</p>
</li>
</ul>
</div>
</section>
</div>
</main>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
</th:block>
</html>

View File

@@ -0,0 +1,108 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
</th:block>
<th:block layout:fragment="layoutContent">
<div class="same">
<aside>
<ul>
<li class="first"><a href="#arginine">아르기닌 주사</a></li>
</ul>
</aside>
<main>
<div id="arginine">
<section class="main_img">
<img class="pc" src="/image/web/diet_main4.jpg" alt="diet"/>
<img class="mb" src="/image/web/Mdiet_main4.jpg" alt="diet"/>
<div class="text_box">
<div class="left_text_box">
<p class="sub_title">산화질소 생성을 도와 비만탈출!</p>
<p class="title">아르기닌 주사</p>
<p class="sub_text">
체내 산화질소 생성을 자극하여 혈관을 확장합니다.<br/>
확장된 혈관은 순환이 잘되기 때문에<br/>
체지방감소, 근육 생성에 도움이 되는 주사제입니다.
</p>
</div>
</div>
</section>
<section class="content1">
<div class="inner_wrap">
<p class="title">아르기닌주사</p>
<p class="sub_title">지방분해를 돕는 아르기닌 성분을 주입하여 자연스럽게 지방분해를 촉진시킵니다.</p>
<p class="sub_text">
방송에 나와 많이 알려진 지방분해 촉진 주사! 지방세포의 지방을 지방산으로 분해해주는 건강한 지방제거 주사.
인체내에서 합성과정을 통해 산화질소(no)를 만들어내는 아미노산의 일종으로 인체내 필요한 산화질소 생성을 돕는 성분인 아르기닌을 주사하여 지방을 분해하는 효과를 얻는 시술입니다.
</p>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<h3><span>시술효과 </span>Effect</h3>
<ul>
<li><p>국소지방감소 <br/>기초대사량증가</p></li>
<li><p>혈액순환 촉진 <br/>손발저림완화</p></li>
<li><p>면역기능강화 <br/>항암효과</p></li>
<li><p>근육량증가 <br/>성기능향상</p></li>
</ul>
</div>
</section>
<section class="content3">
<div class="inner_wrap">
<h3><span>특징 </span>Unique</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>산화질소 생성→ 아르기니의 대사, 지방분해효소 활성화!</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>L-아르기닌→ 평활근(내장근)이완 효소를 활성→ 혈관확장</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>이산화탄소와 노폐물 배출이 용이</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>L-아르기닌으로 생긴 산화질소가 혈액순환을 원활하게!</p>
</li>
</ul>
</div>
</section>
<section class="content4">
<div class="inner_wrap">
<h3><span>시술횟수 </span>Time</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/time.png" alt="check"/></div>
<p>1주 간격으로 5~10회</p>
</li>
</ul>
</div>
</section>
<section class="content5">
<div class="inner_wrap">
<h3><span>주의사항 </span>Notice</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/notice.png" alt="check"/></div>
<p>
개인의 특성에 따라 붓기가 생길수 있습니다.<br/>
시술 부위를 누르거나 문지르는등의 강한 자극은 피합니다.<br/>
시술 후 일주일 동안은 흡연, 음주를 삼갑니다.
</p>
</li>
</ul>
</div>
</section>
</div>
</main>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
</th:block>
</html>

View File

@@ -0,0 +1,290 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/introduction/introductionHospitalSelect.css?v1.0">
</th:block>
<th:block layout:fragment="layoutContent">
<main>
<section class="main_img">
<div class="inner_wrap">
<img src="/image/web/introduction_main.png" alt="introduction"/>
<div class="text_box">
<p class="hashtag">#맞춤진료 #만족스러운결과</p>
<p class="title">
<span>MADE U 강남본점</span><br/>
Total Beauty<br class="mb"/> One Stop System
</p>
<p class="sub_text">
한 공간에서 고객 한분 한분께 자연스러운<br class="mb"/> 아름다움과 건강한 다이어트를 위해<br/>
항상 노력하는 함께하는<br class="mb"/> 조언자가 되어 드릴 것을 약속드립니다.
</p>
</div>
</div>
</section>
<section class="content1">
<div class="inner_wrap">
<div class="text_box">
<p class="hashtag">#차별화된 맞춤 플랜</p>
<p class="title">Looking Around<br/>MADE <span class="red">U</span></p>
<p class="sub_title">
쾌적하고 안락한 공간을 제공하는<br/>
<span>메이드유 강남본점</span>
</p>
<p class="sub_text">
깨끗한 공간, 친절한 상담을 제공<span class="pc">하겠습니다.</span>
</p>
</div>
<img src="/image/web/introduction_content1.png" alt="content1"/>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<p class="mb">쉬운다이어트 방법 없을까?<br/><span>MADE U 시그니처 프로그램</span></p>
<ul>
<li>
<img src="/image/web/introduction_content2-1.png" alt="content2-1"/>
<div class="text_box">
<p>One-On-One Customized Counseling</p>
<p class="sub_title">
MADE U 강남본점만의<br/>
<span>1:1 맞춤 상담</span>
</p>
<p class="sub_text">
고객님의 체형별 그리고 고민<br class="mb"/> 부위별 맞춤진료로,<br/>
숨겨진 아름다움을 찾아드립니다.
</p>
</div>
</li>
<li>
<img src="/image/web/introduction_content2-2.png" alt="content2-2"/>
<div class="text_box">
<p>Trademark Application</p>
<p class="sub_title">
MADE U 강남본점만의<br/>
<span>특허<span class="red"></span>상표 출원</span>
</p>
<p class="sub_text">
메이드유 강남본점에서 자체 개발한<br class="mb"/> 메쉬다 주사<br class="pc"/>
레시피의 뛰어난<br class="mb"/> 효과를 바탕으로 다수의<br/>
특허와 상표를 등록했습니다.
</p>
</div>
</li>
</ul>
</div>
</section>
<section class="content3">
<div class="inner_wrap">
<p>국내 고가명품 최다보유<br><span>MADE U</span> 프리미엄 장비 소개</p>
<div class="equipment-grid">
<div class="equipment-card">
<div class="equipment-image">
<img src="/image/equip/써마지.jpg" alt="써마지">
</div>
<div class="equipment-info">
<h3 class="equipment-name">써마지</h3>
<p class="equipment-desc">깊은 탄력과 리프팅을 동시에</p>
<p class="equipment-price"><!-- 1,800,000<span>부터</span> --></p>
</div>
</div>
<div class="equipment-card">
<div class="equipment-image">
<img src="/image/equip/울쎄라.jpg" alt="울쎄라">
</div>
<div class="equipment-info">
<h3 class="equipment-name">울쎄라</h3>
<p class="equipment-desc">깊은 탄력과 리프팅을 동시에</p>
<p class="equipment-price"><!-- 400,000<span>부터</span> --></p>
</div>
</div>
<div class="equipment-card">
<div class="equipment-image">
<img src="/image/equip/티타늄.jpg" alt="티타늄리프팅">
</div>
<div class="equipment-info">
<h3 class="equipment-name">티타늄리프팅</h3>
<p class="equipment-desc">깊은 탄력과 리프팅을 동시에</p>
<p class="equipment-price"><!-- 600,000<span>부터</span> --></p>
</div>
</div>
<div class="equipment-card">
<div class="equipment-image">
<img src="/image/equip/튠바디.jpg" alt="튠바디">
</div>
<div class="equipment-info">
<h3 class="equipment-name">튠바디</h3>
<p class="equipment-desc">깊은 탄력과 리프팅을 동시에</p>
<p class="equipment-price"><!-- 150,000<span>부터</span> --></p>
</div>
</div>
<!-- 2번째 행 -->
<div class="equipment-card">
<div class="equipment-image">
<img src="/image/equip/튠페이스.jpg" alt="튠페이스">
</div>
<div class="equipment-info">
<h3 class="equipment-name">튠페이스</h3>
<p class="equipment-desc">깊은 탄력과 리프팅을 동시에</p>
<p class="equipment-price"><!-- 400,000<span>부터</span> --></p>
</div>
</div>
<div class="equipment-card">
<div class="equipment-image">
<img src="/image/equip/울핏.jpg" alt="울핏">
</div>
<div class="equipment-info">
<h3 class="equipment-name">울핏</h3>
<p class="equipment-desc">깊은 탄력과 리프팅을 동시에</p>
<p class="equipment-price"><!-- 50,000<span>부터</span> --></p>
</div>
</div>
<div class="equipment-card">
<div class="equipment-image">
<img src="/image/equip/포텐자.jpg" alt="포텐자">
</div>
<div class="equipment-info">
<h3 class="equipment-name">포텐자</h3>
<p class="equipment-desc">깊은 탄력과 리프팅을 동시에</p>
<p class="equipment-price"><!-- 150,000<span>부터</span> --></p>
</div>
</div>
<div class="equipment-card">
<div class="equipment-image">
<img src="/image/equip/인모드.jpg" alt="인모드">
</div>
<div class="equipment-info">
<h3 class="equipment-name">인모드</h3>
<p class="equipment-desc">깊은 탄력과 리프팅을 동시에</p>
<p class="equipment-price"><!-- 100,000<span>부터</span> --></p>
</div>
</div>
<!-- 3번째 행 -->
<div class="equipment-card">
<div class="equipment-image">
<img src="/image/equip/슈링크유니버스.jpg" alt="슈링크유니버스">
</div>
<div class="equipment-info">
<h3 class="equipment-name">슈링크유니버스</h3>
<p class="equipment-desc">깊은 탄력과 리프팅을 동시에</p>
<p class="equipment-price"><!-- 89,000<span>부터</span> --></p>
</div>
</div>
<div class="equipment-card">
<div class="equipment-image">
<img src="/image/equip/바디고주파테라피.jpg" alt="바디고주파테라피">
</div>
<div class="equipment-info">
<h3 class="equipment-name">바디고주파테라피</h3>
<p class="equipment-desc">깊은 탄력과 리프팅을 동시에</p>
<p class="equipment-price"><!-- 100,000<span>부터</span> --></p>
</div>
</div>
<div class="equipment-card">
<div class="equipment-image">
<img src="/image/equip/리포덤.jpg" alt="리포덤">
</div>
<div class="equipment-info">
<h3 class="equipment-name">리포덤</h3>
<p class="equipment-desc">깊은 탄력과 리프팅을 동시에</p>
<p class="equipment-price"><!-- 50,000<span>부터</span> --></p>
</div>
</div>
<div class="equipment-card">
<div class="equipment-image">
<img src="/image/equip/라비앙.jpg" alt="라비앙">
</div>
<div class="equipment-info">
<h3 class="equipment-name">라비앙</h3>
<p class="equipment-desc">깊은 탄력과 리프팅을 동시에</p>
<p class="equipment-price"><!-- 165,000<span>부터</span> --></p>
</div>
</div>
</div>
</div>
</section>
<section class="content4">
<div class="inner_wrap">
<p>
한 공간에서 고객 한분 한분께 자연스러운 아름다움과<br class="mb"/> 건강한 다이어트를 위해 항상 노력하는<br/>
<span>Total Beauty One Stop System</span>
</p>
<ul>
<li class="first">
<div class="text_box">
<p>
<span>
자연스러운 아름다움과<br/>
건강한 다이어트
</span>
</p>
<p>
메이드유는 <span>Total Beauty One Stop System</span>으로<br class="pc"/>
한 공간에서 고객 한분 <br class="mb"/>한분께 자연스러운 아름다움과<br/>
건강한 다이어트를 위해 항상 노력하는 함께하는 조언자가<br class="pc"/>
되어 드릴 것을 약속드립니다.
</p>
</div>
<img class="pc" src="/image/web/introduction_content4-1.jpg" alt="introduction_content4-1"/>
<img class="mb" src="/image/web/Mintroduction_content4-1.jpg" alt="introduction_content4-1"/>
</li>
<li class="red_box">
<div class="text_box">
<p>
<span>고객을 가족으로 생각하는 마음으로<br class="pc"/>정직한 시술, <br class="mb"/>만족할 수 있는 결과,</span><br/>
더 나은 감동을 선사하기 위해<br/>
끊임없이 노력하겠습니다.
</p>
<p>
메이드유는 <span>전국, 해외에서 찾아오는 비만센터와<br class="pc"/> 프리미멈 명품
장비 보유 및 장비 최다 보유</span>와 엘란쎄, <br class="pc"/>스컬트라 콜라겐 볼륨
전국 3대 병원인 쁘띠 센터로 <br class="pc"/>구분되어 고객에 맞춰 운영되고
있습니다.
</p>
</div>
<img class="pc" src="/image/web/introduction_content4-2.jpg" alt="introduction_content4-2"/>
<img class="mb" src="/image/web/Mintroduction_content4-2.jpg" alt="introduction_content4-2"/>
</li>
<li>
<div class="text_box">
<p>
No Pain 통증 없이<br/>
No Bruise 멍 없이<br/>
No Swelling 붓기 없이<br/>
<span>3No 의료서비스를 지향</span>
</p>
<p>
모든 제품은 정품, 정량, 정품 장비 사용을 원칙으로 안전을 <br class="pc"/>
최우선으로 하고 있으며, 모든 시술은 <span>No Pain, No Bruise, <br class="pc"/>
No Swelling라는 3No 의료서비스를 지향</span>합니다. <br class="pc"/>
앞으로도 고품질의 관리와 서비스를 받을 수 있도록 노력하며 <br class="pc"/>
사소한 불편까지 읽어주는 세심한 배려, 마음까지 읽는 서비스로<br class="pc"/>
무한 감동을 드릴 것을 약속합니다.
</p>
</div>
<img class="pc" src="/image/web/introduction_content4-3.jpg" alt="introduction_content4-3"/>
<img class="mb" src="/image/web/Mintroduction_content4-3.jpg" alt="introduction_content4-3"/>
</li>
</ul>
</div>
</section>
</main>
</th:block>
<th:block layout:fragment="layoutContentScript">
</th:block>
</html>

View File

@@ -0,0 +1,120 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/introduction/introductionPriceSelect.css?v1.0">
</th:block>
<th:block layout:fragment="layoutContent">
<main>
<section class="content1">
<div class="inner_wrap">
<div class="text_box">
<p class="hashtag">#맞춤진료 #합리적인 비용</p>
<p class="title">
<span>MADE U 강남본점</span><br/>
비급여 안내
</p>
<p class="sub_text">
고객님이 원하시는 아름다움을 찾기<br class="mb"/> 위해,<br class="pc"/>
고객님별 그리고 고민하시는<br class="mb"/> 부위별 맞춤 진료를 하겠습니다.
</p>
</div>
<div class="table_box">
<img class="mb" src="/image/web/price.png" alt="price"/>
<table class="pc">
<tr class="thead">
<td colspan="2">분류</td>
<td colspan="2">항목</td>
<td colspan="2">진료 비용 등<br class="mb"/>(단위:원)</td>
<td rowspan="2">특이사항</td>
<td rowspan="2">비고</td>
</tr>
<tr class="sub_thead">
<td>중분류</td>
<td>소분류</td>
<td>코드</td>
<td>명칭</td>
<td>구분</td>
<td>비용</td>
</tr>
<tr>
<td>기본진료료</td>
<td>기본진료료</td>
<td></td>
<td>기본진료료</td>
<td></td>
<td>10,000</td>
<td></td>
<td></td>
</tr>
<tr>
<td>제증명수수료</td>
<td>제증명수수료</td>
<td></td>
<td>진단서</td>
<td></td>
<td>30,000</td>
<td></td>
<td></td>
</tr>
<tr>
<td>제증명수수료</td>
<td>제증명수수료</td>
<td></td>
<td>진료확인서</td>
<td></td>
<td>10,000</td>
<td></td>
<td></td>
</tr>
<tr>
<td>제증명수수료</td>
<td>제증명수수료</td>
<td></td>
<td>통원확인서</td>
<td></td>
<td>10,000</td>
<td></td>
<td></td>
</tr>
<tr>
<td>제증명수수료</td>
<td>제증명수수료</td>
<td></td>
<td>의무기록사본</td>
<td></td>
<td>10,000</td>
<td>진료기록부</td>
<td></td>
</tr>
<tr>
<td>제증명수수료</td>
<td>제증명수수료</td>
<td></td>
<td>의무기록사본 추가</td>
<td></td>
<td>1,000</td>
<td>진료기록부</td>
<td>장당</td>
</tr>
<tr>
<td>제증명수수료</td>
<td>제증명수수료</td>
<td></td>
<td>제증명발급</td>
<td></td>
<td>1,000</td>
<td>처방전 포함</td>
<td>장당</td>
</tr>
</table>
</div>
</div>
</section>
</main>
</th:block>
<th:block layout:fragment="layoutContentScript">
</th:block>
</html>

View File

@@ -0,0 +1,131 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/introduction/introductionStaffSelect.css?v1.0">
</th:block>
<th:block layout:fragment="layoutContent">
<main>
<section class="main_img">
<!-- 2025.09.03 요구사항으로 인한 주석처리 byPJS <img src="/image/web/staff_main.png" alt="staff_main"/> -->
</section>
<section class="content1">
<div class="inner_wrap">
<div class="captain_box">
<img class="pc" src="/image/web/staff_cont1.jpg" alt="captain" />
<img class="mb" src="/image/web/Mstaff_cont1.jpg" alt="captain" />
<div class="text_box">
<p class="sub_title">메이드유 강남본점 <span>대표원장 박재우</span></p>
<p class="title">Specialist</p>
<p class="sub_text">
메이드유 강남본점의 전문의료진은<br class="pc"/>
아름다움 극대화를 <br class="mb"/>위해 끊임없이 연구하고 노력합니다.
</p>
</div>
</div>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<p>본연의 장점을 살려주는 것이 변화의 시작!<br/><span>MADE U 전문의료진 소개</span></p>
<ul>
<li>
<img src="/image/web/profile1.jpg" alt="profile"/>
<div class="text_box">
<p class="field">
<span>비만</span>
</p>
<p class="name">
<span class="name">박재우</span>
대표원장 / <span>Chief Medical Director</span>
</p>
<p class="last">
<span>Profile</span><br/>
&#41; 메이드유의원 프랜차이즈 대표원장 <br/>
&#41; 메이드유의원 강남본점 대표원장 <br/>
&#41; 메이드유의원 비만센터 대표원장 <br/>
대한미용외과학회 회원 <br/>
대한미용성형레이저의학회 회원 <br/>
대한비만치료학회 회원
</p>
</div>
</li>
<li>
<img src="/image/web/profile2.png" alt="profile"/>
<div class="text_box">
<p class="field">
<span>피부</span>
<span>쁘띠</span>
<span>제모</span>
</p>
<p class="name">
<span class="name">김종효</span>
대표원장 / <span>Medical Director</span>
</p>
<p class="last">
<span>Profile</span><br/>
&#41; 메이드유의원 강남본점 원장 <br/>
&#41; 메이드유의원 명동점 대표원장 <br/>
&#41; 톡스앤필 홍대신촌 원장 <br/>
대한레이저피부모발학회 회원 <br/>
대한미용외과학회 회원 <br/>
한국미용성형학회 회원
</p>
</div>
</li>
<!-- <li> 2025.09.03 요구사항으로 인한 주석처리 byPJS
<img src="/image/web/profile3.png" alt="profile"/>
<div class="text_box">
<p class="field">
<span>비만</span>
<span>쁘띠</span>
<span>피부</span>
<span>제모</span>
</p>
<p class="name">
<span class="name">신다은</span>
원장 / <span>Medical Director</span>
</p>
<p class="last">
<span>Profile</span><br/>
현&#41; 메이드유의원 강남본점 원장<br/>
대한레이저피부모발학회 회원<br/>
대한미용외과학회 회원<br/>
대한리프팅연구회 회원<br/>
한국미용성형학회 회원
</p>
</div>
</li> -->
<li>
<img src="/image/web/profile4.png" alt="profile"/>
<div class="text_box">
<p class="field">
<span>피부</span>
<span>쁘띠</span>
<span>제모</span>
</p>
<p class="name">
<span class="name">김준혁</span>
원장 / <span>Medical Director</span>
</p>
<p class="last">
<span>Profile</span><br/>
&#41; 메이드유의원 강남본점 원장<br/>
&#41; JD클리닉 신사점 원장<br/>
&#41; 팝루미에의원 강남점 원장<br/>
대한리프팅연구회 회원<br/>
대한비만치료학회 회원<br/>
대한미용성형레이저의학회 회원
</p>
</div>
</li>
</ul>
</div>
</section>
</main>
</th:block>
<th:block layout:fragment="layoutContentScript">
</th:block>
</html>

View File

@@ -0,0 +1,98 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/introduction/introductionWaySelect.css?v1.0">
</th:block>
<th:block layout:fragment="layoutContent">
<main>
<section class="main_img">
<ul>
<li><img src="/image/web/introduction_way_main1.jpg" alt="way"/></li>
<li><img src="/image/web/introduction_way_main2.jpg" alt="way"/></li>
<li><img src="/image/web/introduction_way_main3.jpg" alt="way"/></li>
</ul>
</section>
<section class="content1">
<div class="inner_wrap">
<p>7호선 논현역 / 신분당선 논현역 3번 출구<br/><span>MADE U 강남본점 위치 안내</span></p>
<div class="top">
<div class="img_box img_left">
<img src="/image/web/introduction_way_con1_1.png" alt="way"/>
</div>
<div class="img_box img_right">
<img src="/image/web/introduction_way_con1_2.png" alt="way"/>
</div>
<div class="text_box">
<p>도보 <span>2분 거리</span></p>
</div>
</div>
<div class="btm">
<ul>
<li class="red">논현역 <br class="mb"/>3번 출구</li>
<li>뚜레쥬르 <br class="mb"/>카페</li>
<li>HOLLYS <br class="mb"/>COFFEE</li>
<li class="red">메이드유 <br class="mb"/>빌딩</li>
</ul>
</div>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<!-- * 카카오맵 - 지도퍼가기 -->
<!-- 1. 지도 노드 -->
<div id="daumRoughmapContainer1757836409022" class="root_daum_roughmap root_daum_roughmap_landing"></div>
<!--
2. 설치 스크립트
* 지도 퍼가기 서비스를 2개 이상 넣을 경우, 설치 스크립트는 하나만 삽입합니다.
-->
<script charset="UTF-8" class="daum_roughmap_loader_script" src="https://ssl.daumcdn.net/dmaps/map_js_init/roughmapLoader.js"></script>
<!-- 3. 실행 스크립트 -->
<script charset="UTF-8">
new daum.roughmap.Lander({
"timestamp" : "1757836409022",
"key" : "wao8xnsxkey",
"mapWidth" : "1280",
"mapHeight" : "900"
}).render();
</script>
</div>
</section>
<section class="content4">
<div class="inner_wrap">
<ul>
<li><img src="/image/web/introduction_way_con4_1.jpg" alt="way"></li>
<li><img src="/image/web/introduction_way_con4_2.jpg" alt="way"></li>
<li class="pc"><img src="/image/web/introduction_way_con4_3.jpg" alt="way"></li>
</ul>
<div>
<div class="left_box">
<p>Contact <span class="red">MADE</span> U</p>
<p>
정보를 남겨주시면, 빠르게 확인 후 연락드리겠습니다.<br/>
다이어트에 대한 고민을 메이드유 강남본점과 상의하세요
</p>
</div>
<div class="right_box">
<p>빠른 상담 예약 <span>02.547.4711</span></p>
<button onclick="window.open('https://booking.naver.com/booking/6/bizes/162191')">
<!-- <img class="naver_img" src="/image/web/naver.svg" alt="naver"/> -->
<span>네이버 예약 </span> 바로가기
<img src="/image/web/arrow2.svg" alt="arrow"/>
</button>
</div>
</div>
</div>
</section>
</main>
</th:block>
<th:block layout:fragment="layoutContentScript">
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=5b8e8d554e06d9b6cd5f1fb628ed301a&libraries=services"></script>
<script src="/js/web/introduction/introductionWaySelect.js"></script>
</th:block>
</html>

View File

@@ -0,0 +1,27 @@
<!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">
<head>
<th:block th:replace="/web/layout/layoutHead :: layoutHead"></th:block>
</head>
<body>
<!-- 상단 스크립트 타임리프 변수 선언 -->
<th:block layout:fragment="layout_top_script"></th:block>
<div class="project_wrap">
<th:block th:replace="/web/layout/layoutHeader :: layoutHeader"></th:block>
<!-- 오른쪽내용 -->
<th:block layout:fragment="layoutContent"></th:block>
<th:block th:replace="/web/layout/layoutFooter :: layoutFooter"></th:block>
</div>
<!-- 모달 -->
<th:block layout:fragment="layoutContentModal"></th:block>
<!-- 스크립트 -->
<th:block layout:fragment="layoutContentScript"></th:block>
</body>
</html>

View File

@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<th:block th:fragment="layoutFooter">
<!-- footer_section -->
<footer>
<div class="inner_wrap">
<div class="text_box">
<img class="fLogo" src="/image/logo_121x33_W.png" alt="logo"/>
<a href="/webaccept/acceptSite.do">사이트 이용약관</a>
<a href="/webaccept/acceptPrivacy.do">개인정보처리방침</a>
<ul>
<li>상호명 : 메이드유의원&emsp;|&emsp;</li>
<li>서울특별시 강남구 강남대로 516, 2,3,4층(논현동, 메이드유빌딩)&emsp;|&emsp;</li>
<li>대표 : 박재우&emsp;|&emsp;</li>
<li>전화 : 02-547-4711&emsp;|&emsp;</li>
<li>팩스 : 070-5226-3771&emsp;|&emsp;</li>
<li>사업자등록번호 : 490-12-01321&emsp;|&emsp;</li>
<li>E-mail : imadeu@naver.com</li>
</ul>
</div>
</div>
</footer>
</th:block>
</html>

View File

@@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<th:block th:fragment="layoutHead">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="keyword" content="HTML, meta, tag, element, reference">
<meta name="author" content="NTSOFT">
<meta name="description" content={props.description} data-react-helmet="true" />
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<meta http-equiv="Cache-Control" content="No-Cache" />
<meta http-equiv="pragma" content="No-cache" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE10">
<!-- sns미리보기 -->
<meta property="og:type" content="website">
<!-- <meta property="og:url" content="https://ntsoft.kr/"> -->
<meta property="og:image" content="">
<meta property="og:title" content="메이드유">
<meta property="og:description" content="설명문구">
<!-- 사이트등록및소유확인 -->
<meta name="naver-site-verification" content="" />
<title>메이드유</title>
<!-- 파비콘 -->
<link rel="shortcut icon" href="" type="image/x-icon">
<link rel="icon" href="" type="image/x-icon">
<!-- 적용css -->
<link rel="stylesheet" href="/css/normalize.min.css">
<link rel="stylesheet" href="/css/web/header.css">
<link rel="stylesheet" href="/css/web/footer.css">
<link rel="stylesheet" href="/css/web/modal.css">
<link rel="stylesheet" href="/css/web/modal_styles.css">
<link rel="stylesheet" href="/css/web/common.css">
<link rel="stylesheet" href="/css/web/font.css">
<link rel="stylesheet" href="/css/web/jquery-ui.css">
<link rel="stylesheet" href="/css/web/swiper-bundle.min.css">
<th:block layout:fragment="layoutCss"></th:block>
<!-- 베이스script -->
<script src="/js/jquery.min.js"></script>
<!-- 적용script -->
<script src="/js/jquery-ui.js"></script>
<script src="/js/swiper-bundle.min.js"></script>
<script src="/js/web/common.js"></script>
</th:block>
</html>

View File

@@ -0,0 +1,99 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<th:block th:fragment="layoutHeader">
<th:block th:replace="/web/layout/layoutModal :: layoutModal"></th:block>
<link rel="stylesheet" href="/css/web/quick_menu/quick_menu.css">
<script>
// 디바이스 감지 함수
function isMobileDevice() {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
|| window.innerWidth <= 768;
}
function movePetitCenter(){
window.location.href="https://petit.madeu.co.kr/index";
}
// 카카오톡 상담 함수 (모든 디바이스에서 동작)
function openKakaoTalk() {
window.open('https://pf.kakao.com/_puZExd', '_blank');
}
// 전화걸기 함수 (모바일에서만 동작)
function makePhoneCall() {
if (isMobileDevice()) {
// 모바일에서만 전화걸기
window.location.href = 'tel:02-547-4711';
} else {
// 데스크톱에서는 동작 안함 (필요시 알림 추가)
console.log('전화걸기는 모바일에서만 가능합니다.');
}
}
// 모바일 여부 확인 함수
function isMobile() {
return window.innerWidth <= 768; // 필요 시 기준 너비 조정
}
// 현재 경로가 /index인지 확인
function isIndexPage() {
return window.location.pathname === '/index'; // '/index.html'인 경우 조정 필요
}
// 퀵메뉴 표시/숨김 함수
function toggleQuickMenu() {
const quickMenu = document.querySelector('.quick-menu-simple');
if (!quickMenu) return; // 요소가 없으면 종료
if (isMobile()) {
// 모바일: /index일 때만 표시
quickMenu.style.display = isIndexPage() ? '' : 'none';
} else {
// 데스크톱: 항상 표시
quickMenu.style.display = '';
}
}
// 페이지 로드와 리사이즈 이벤트 연결
window.addEventListener('load', toggleQuickMenu);
window.addEventListener('resize', toggleQuickMenu);
</script>
<header>
<div class="inner_wrap">
<button class="mb mbmenu" onClick="openNav()"></button>
<a class="logo" href="/index"><img src="/image/logo_199x54.png" alt="logo"></a>
<nav>
<ul class="depth1">
<li th:each="menu : ${menuList}">
<a class="mmenu" th:href="${menu.menuUrl}" th:text="${menu.menuName}"></a>
<ul class="depth2" th:if="${#lists.size(menu.children) > 0}">
<li></li>
<li th:each="subMenu : ${menu.children}">
<a th:href="${subMenu.menuUrl}" th:text="${subMenu.menuName}"></a>
</li>
</ul>
</li>
</ul>
</nav>
</div>
</header>
<!-- 퀵메뉴 -->
<div class="quick-menu-simple">
<div class="quick-item" onclick="movePetitCenter()">
<img src="/image/quick_menu/petit_center.png" alt="쁘띠센터">
</div>
<!-- 카카오톡 상담 -->
<div class="quick-item kakao-consult" onclick="openKakaoTalk()">
<img src="/image/quick_menu/kakao_consultation.png" alt="카카오톡 상담">
</div>
<!-- 전화 상담 -->
<div class="quick-item phone-consult" onclick="makePhoneCall()">
<div class="phone-default">
<img src="/image/quick_menu/call_consultation.png" alt="전화 상담">
</div>
<div class="phone-number">
<img src="/image/quick_menu/madeu_phone_number.png" alt="전화 상담">
</div>
</div>
</div>
<script src="/js/web/layout/layoutHeader.js?ver=1"></script>
</th:block>
</html>

View File

@@ -0,0 +1,351 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<th:block th:fragment="layoutModal">
<div id="modalBox"></div>
<script>
<!-- success Modal 셋팅 -->
function fn_setSuccessModal(targetId){
let successModalHTML = '';
successModalHTML += '<div class="success popupColored">';
successModalHTML += ' <div class="modal modal_success" id="'+targetId+'" role="dialog" style="padding-right: 17px;">';
successModalHTML += ' <div class="modal-dialog">';
successModalHTML += ' <div class="modal-content">';
successModalHTML += ' <div class="modal-header">';
successModalHTML += ' <div class="modal-name successTextBox">';
successModalHTML += ' <svg xmlns="http://www.w3.org/2000/svg" width="52.012" height="52.012" viewBox="0 0 52.012 52.012">';
successModalHTML += ' <g id="그룹_1" data-name="그룹 1" transform="translate(-41 -25)">';
successModalHTML += ' <g id="patch-check" transform="translate(41.751 25.501)">';
successModalHTML += ' <path id="패스_1" data-name="패스 1" d="M22.406,6.477a1.625,1.625,0,0,1,0,2.3L12.654,18.53a1.625,1.625,0,0,1-2.3,0L5.476,13.654a1.627,1.627,0,1,1,2.3-2.3L11.5,15.081l8.6-8.6a1.625,1.625,0,0,1,2.3,0Z" transform="translate(11.25 13.5)" fill-rule="evenodd"/>';
successModalHTML += ' </g>';
successModalHTML += ' <g id="pause-circle" transform="translate(41 25)">';
successModalHTML += ' <path id="패스_10" data-name="패스 10" d="M26.006,48.761A22.755,22.755,0,1,1,48.761,26.006,22.755,22.755,0,0,1,26.006,48.761Zm0,3.251A26.006,26.006,0,1,0,0,26.006,26.006,26.006,0,0,0,26.006,52.012Z"/>';
successModalHTML += ' </g>';
successModalHTML += ' </g>';
successModalHTML += ' </svg>';
successModalHTML += ' <p class="title"><!-- 문구입력 --></p>';
successModalHTML += ' <p class="text"><!-- 문구입력 --></p>';
successModalHTML += ' </div>';
successModalHTML += ' </div>';
successModalHTML += ' <div class="modal-footer">';
successModalHTML += ' <div class="btn-box">';
successModalHTML += ' <button type="button" class="btn btnCommon btn-Success" style="outline:none;">확인</button>';
successModalHTML += ' </div>';
successModalHTML += ' </div>';
successModalHTML += ' </div>';
successModalHTML += ' </div>';
successModalHTML += ' </div>';
successModalHTML += '</div>';
$("#modalBox").append(successModalHTML);
}
<!-- danger Modal 셋팅 -->
function fn_setDangerModal(targetId){
let dangerModalHTML = '';
dangerModalHTML += '<div class="danger popupColored">';
dangerModalHTML += ' <div class="modal modal_danger" id="'+targetId+'" role="dialog" style="padding-right: 17px;">';
dangerModalHTML += ' <div class="modal-dialog">';
dangerModalHTML += ' <div class="modal-content">';
dangerModalHTML += ' <div class="modal-header">';
dangerModalHTML += ' <div class="modal-name dangerTextBox">';
dangerModalHTML += ' <svg xmlns="http://www.w3.org/2000/svg" width="52.012" height="52.012" viewBox="0 0 52.012 52.012">';
dangerModalHTML += ' <g id="그룹_3" data-name="그룹 3" transform="translate(-301 -25)">';
dangerModalHTML += ' <path id="패스_5" data-name="패스 5" d="M13.627,5.5a1.625,1.625,0,0,1,1.625,1.625V12h4.876a1.625,1.625,0,0,1,0,3.251H15.252v4.876a1.625,1.625,0,0,1-3.251,0V15.252H7.125a1.625,1.625,0,0,1,0-3.251H12V7.125A1.625,1.625,0,0,1,13.627,5.5Z" transform="translate(308.222 51.493) rotate(-45)" fill-rule="evenodd"/>';
dangerModalHTML += ' <g id="pause-circle" transform="translate(301 25)">';
dangerModalHTML += ' <path id="패스_10" data-name="패스 10" d="M26.006,48.761A22.755,22.755,0,1,1,48.761,26.006,22.755,22.755,0,0,1,26.006,48.761Zm0,3.251A26.006,26.006,0,1,0,0,26.006,26.006,26.006,0,0,0,26.006,52.012Z"/>';
dangerModalHTML += ' </g>';
dangerModalHTML += ' </g>';
dangerModalHTML += ' </svg>';
dangerModalHTML += ' <p class="title"><!-- 문구입력 --></p>';
dangerModalHTML += ' <p class="text"><!-- 문구입력 --></p>';
dangerModalHTML += ' </div>';
dangerModalHTML += ' </div>';
dangerModalHTML += ' <div class="modal-footer">';
dangerModalHTML += ' <div class="btn-box">';
dangerModalHTML += ' <button type="button" class="btn btnCommon btn-Success" style="outline:none;">확인</button>';
dangerModalHTML += ' </div>';
dangerModalHTML += ' </div>';
dangerModalHTML += ' </div>';
dangerModalHTML += ' </div>';
dangerModalHTML += ' </div>';
dangerModalHTML += '</div>';
$("#modalBox").append(dangerModalHTML);
}
<!-- warning Modal 셋팅 -->
function fn_setWarningModal(targetId){
let warningModalHTML = '';
warningModalHTML += '<div class="warning popupColored">';
warningModalHTML += ' <div class="modal modal_warning" id="'+targetId+'" role="dialog" style="padding-right: 17px;">';
warningModalHTML += ' <div class="modal-dialog">';
warningModalHTML += ' <div class="modal-content">';
warningModalHTML += ' <div class="modal-header">';
warningModalHTML += ' <div class="modal-name warningTextBox">';
warningModalHTML += ' <svg xmlns="http://www.w3.org/2000/svg" width="52.012" height="52.012" viewBox="0 0 52.012 52.012">';
warningModalHTML += ' <g id="그룹_2" data-name="그룹 2" transform="translate(-171 -25)">';
warningModalHTML += ' <path id="패스_3" data-name="패스 3" d="M7,26.767a3.251,3.251,0,1,1,3.251,3.251A3.251,3.251,0,0,1,7,26.767ZM7.323,7.246a2.942,2.942,0,1,1,5.851,0l-1.138,11.4a1.8,1.8,0,0,1-3.576,0Z" transform="translate(186.999 34.005)"/>';
warningModalHTML += ' <g id="pause-circle" transform="translate(171 25)">';
warningModalHTML += ' <path id="패스_10" data-name="패스 10" d="M26.006,48.761A22.755,22.755,0,1,1,48.761,26.006,22.755,22.755,0,0,1,26.006,48.761Zm0,3.251A26.006,26.006,0,1,0,0,26.006,26.006,26.006,0,0,0,26.006,52.012Z"/>';
warningModalHTML += ' </g>';
warningModalHTML += ' </g>';
warningModalHTML += ' </svg>';
warningModalHTML += ' <p class="title"><!-- 문구입력 --></p>';
warningModalHTML += ' <p class="text"><!-- 문구입력 --></p>';
warningModalHTML += ' </div>';
warningModalHTML += ' </div>';
warningModalHTML += ' <div class="modal-footer">';
warningModalHTML += ' <div class="btn-box">';
//warningModalHTML += ' <button type="button" class="btn btnCommon btn-cancel" style="outline:none;">취소</button>';
warningModalHTML += ' <button type="button" class="btn btnCommon btn-Success" style="outline:none;">확인</button>';
warningModalHTML += ' </div>';
warningModalHTML += ' </div>';
warningModalHTML += ' </div>';
warningModalHTML += ' </div>';
warningModalHTML += ' </div>';
warningModalHTML += '</div>';
$("#modalBox").append(warningModalHTML);
}
<!-- info Modal 셋팅 -->
function fn_setInfoModal(targetId){
let infoModalHTML = '';
infoModalHTML += '<div class="info popupColored">';
infoModalHTML += ' <div class="modal modal_info" id="'+targetId+'"role="dialog" style="padding-right: 17px;">';
infoModalHTML += ' <div class="modal-dialog">';
infoModalHTML += ' <div class="modal-content">';
infoModalHTML += ' <div class="modal-header">';
infoModalHTML += ' <div class="modal-name infoTextBox">';
infoModalHTML += ' <svg xmlns="http://www.w3.org/2000/svg" width="52.012" height="52.012" viewBox="0 0 52.012 52.012">';
infoModalHTML += ' <g id="그룹_4" data-name="그룹 4" transform="translate(-431 -25)">';
infoModalHTML += ' <g id="그룹_4-2" data-name="그룹 4" transform="translate(-1.004 0.625)">';
infoModalHTML += ' <path id="패스_7" data-name="패스 7" d="M12.664,23.33c1.092,0,1.638-.78,1.8-2.038.13-1.736.644-2.649,2.753-4.1a7.385,7.385,0,0,0,3.41-6.456A6.939,6.939,0,0,0,13.275,3.5C9.96,3.5,7.45,5.1,6.449,7.693A5.559,5.559,0,0,0,6,9.936c0,1.278.66,2.08,1.772,2.08.884,0,1.479-.478,1.833-1.658.514-1.924,1.707-2.974,3.491-2.974a3.285,3.285,0,0,1,3.348,3.524c0,1.83-.676,2.877-2.672,4.307a6.041,6.041,0,0,0-3.01,5.331v.361C10.763,22.3,11.439,23.33,12.664,23.33Z" transform="translate(445.004 32.875)"/>';
infoModalHTML += ' <path id="패스_9" data-name="패스 9" d="M7,13.251A3.251,3.251,0,1,1,10.252,16.5,3.251,3.251,0,0,1,7,13.251Z" transform="translate(447.258 47.505)"/>';
infoModalHTML += ' </g>';
infoModalHTML += ' <g id="pause-circle" transform="translate(431 25)">';
infoModalHTML += ' <path id="패스_10" data-name="패스 10" d="M26.006,48.761A22.755,22.755,0,1,1,48.761,26.006,22.755,22.755,0,0,1,26.006,48.761Zm0,3.251A26.006,26.006,0,1,0,0,26.006,26.006,26.006,0,0,0,26.006,52.012Z"/>';
infoModalHTML += ' </g>';
infoModalHTML += ' </g>';
infoModalHTML += ' </svg>';
infoModalHTML += ' <p class="title"><!-- 문구입력 --></p>';
infoModalHTML += ' <p class="text"><!-- 문구입력 --></p>';
infoModalHTML += ' </div>';
infoModalHTML += ' </div>';
infoModalHTML += ' <div class="modal-footer">';
infoModalHTML += ' <div class="btn-box">';
infoModalHTML += ' <button type="button" class="btn btnCommon btn-cancel" style="outline:none;">취소</button>';
infoModalHTML += ' <button type="button" class="btn btnCommon btn-Success" style="outline:none;">확인</button>';
infoModalHTML += ' </div>';
infoModalHTML += ' </div>';
infoModalHTML += ' </div>';
infoModalHTML += ' </div>';
infoModalHTML += ' </div>';
infoModalHTML += '</div>';
$("#modalBox").append(infoModalHTML);
}
<!-- 팝업 -->
let modalEvent = {
open : function(target, tit, msg){
if(target.length < 1){
throw new Error("there is no target element !");
}
target.find(".modal-header>.modal-name>.title").html(tit);
//엔터 처리
let enterMsg = msg;//msg.replace(/\r?\n/g, '<br>');
target.find(".modal-header>.modal-name>.text").html(enterMsg);
target.modal({keyboard:false, backdrop:'static'});
},
close : function(target){
//팝업 지우기
//target.modal("hide");
//target.parent().remove();
$("#modalBox .modal").modal("hide");
$("#modalBox").children().remove();
},
success : function(tit, msg, callback){
//alert 팝업
//$(".modal_success .btn-Success").unbind("click");
if($("#modalBox > .popupColored").length > 0){
modalEvent.close();
}
// 모달 아이디 생성
let nowMilli = Date.now();
let targetId = "modal_success"+nowMilli;
// 모달 셋팅
fn_setSuccessModal(targetId);
// 현재 모달 설정
let target = $("#"+targetId);
// 모달 열기
modalEvent.open(target, tit, msg);
// 모달 이벤트
$("#"+targetId+" .btn-Success").click(function(e){
modalEvent.close();
if(typeof callback != 'undefined' && callback){
if(typeof callback == 'function'){
callback();
} else {
if( callback ) {
eval( callback );
}
}
}
});
},
danger : function(tit, msg, callback){
//alert 팝업
//$(".modal_danger .btn-Success").unbind("click");
if($("#modalBox > .popupColored").length > 0){
modalEvent.close();
}
// 모달 아이디 생성
let nowMilli = Date.now();
let targetId = "modal_danger"+nowMilli;
// 모달 셋팅
fn_setDangerModal(targetId);
// 현재 모달 설정
let target = $("#"+targetId);
// 모달 열기
modalEvent.open(target, tit, msg);
// 모달 이벤트
$("#"+targetId+" .btn-Success").click(function(e){
modalEvent.close();
if(typeof callback != 'undefined' && callback){
if(typeof callback == 'function'){
callback();
} else {
if( callback ) {
eval( callback );
}
}
}
});
},
warning : function(tit, msg, callback){
//alert 팝업
//$(".modal_warning .btn-Success").unbind("click");
if($("#modalBox > .popupColored").length > 0){
modalEvent.close();
}
// 모달 아이디 생성
let nowMilli = Date.now();
let targetId = "modal_warning"+nowMilli;
// 모달 셋팅
fn_setWarningModal(targetId);
// 현재 모달 설정
let target = $("#"+targetId);
// 모달 열기
modalEvent.open(target, tit, msg);
// 모달 이벤트
$("#"+targetId+" .btn-Success").click(function(e){
modalEvent.close();
if(typeof callback != 'undefined' && callback){
if(typeof callback == 'function'){
callback();
} else {
if( callback ) {
eval( callback );
}
}
}
});
},
info : function(tit, msg, callback, callback2){
//alert 팝업
//$(".modal_info .btn-Success").unbind("click");
if($("#modalBox > .popupColored").length > 0){
modalEvent.close();
}
// 모달 아이디 생성
let nowMilli = Date.now();
let targetId = "modal_info"+nowMilli;
// 모달 셋팅
fn_setInfoModal(targetId);
// 현재 모달 설정
let target = $("#"+targetId);
// 모달 열기
modalEvent.open(target, tit, msg);
// 모달 확인 이벤트
$("#"+targetId+" .btn-Success").click(function(e){
modalEvent.close();
if(typeof callback != 'undefined' && callback){
if(typeof callback == 'function'){
callback();
} else {
if( callback ) {
eval( callback );
}
}
}
});
// 모달 취소 이벤트
$("#"+targetId+" .btn-cancel").click(function(e){
modalEvent.close();
if(typeof callback2 != 'undefined' && callback2){
if(typeof callback2 == 'function'){
callback2();
} else {
if( callback2 ) {
eval( callback2 );
}
}
}
});
}
}
// 다중 팝업 index 조정
$(document).on('show.bs.modal', '.modal', function (event) {
let zIndex = 1040 + (10 * $('.modal:visible').length);
$(this).css('z-index', zIndex);
setTimeout(function() {
$('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
}, 0);
});
</script>
</th:block>
</html>

View File

@@ -0,0 +1,115 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/petit/petitAntiagingSelect.css?v1.0">
</th:block>
<th:block layout:fragment="layoutContent">
<div class="same">
<aside>
<ul>
<li class="first"><a href="#skinbooster">스킨부스터</a></li>
<li><a href="#wellbeing">웰빙주사</a></li>
</ul>
</aside>
<main>
<!-- 스킨부스터 -->
<div id="skinbooster">
<section class="main_img">
<img class="pc" src="/image/web/petit_main3.jpg" alt="diet"/>
<img class="mb" src="/image/web/Mpetit_main3.jpg" alt="diet"/>
<div class="text_box">
<div class="left_text_box">
<p class="sub_title">피부의 재생력을 높여 탄력있고 밝은 피부!</p>
<p class="title"><span>Skin Booster</span></p>
<p class="sub_text">
<span>스트레스, 환경요인, 노화 등의 여러가지 요인으로 인해<br />
발생한 피부 문제를 간단하게 해결할 수 있는 주사제</span>
</p>
</div>
</div>
</section>
<section class="content1">
<div class="inner_wrap">
<p class="title">Skin Booster</p>
<p class="sub_title">더모톡신 스킨부스터</p>
<p class="sub_text">
피부를 뜻하는 더마와 보툴리눔 톡신의 톡신 합성어로 피부에 보툴리눔 톡신을 주사하는 치료법입니다.
근육층에 주로 주사를 놓아서 주름을 제거하는 보톡스와 달리 보툴리눔 톡신과 비타민, 미네랄 등을 함께 믹스한 용액을 피부 진피, 피하 지방층에 소량씩 주사합니다.
주름개선, 피부탄력 및 리프팅 효과를 주며 엷은 모공이나 여드름 흉터 치료 등 전체적인 얼굴 피부와 윤곽을 개선합니다.
</p>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<h3><span>시술효과 </span>Effect</h3>
<ul>
<li><p>강력한 수분감 <br/>잔주름 개선과 <br/>피부탄력증대 <br/>수분 함유율 증대</p></li>
<li><p>주름 및 탄력개선 <br/>나이가 들면서 감소하는 <br/>피부의 연조직 보충</p></li>
<li><p>환한 피부톤 <br/>얼굴의 윤기와 <br/>볼륨감 부여</p></li>
<li><p>흔적없는 시술 <br/>짧은 시술 시간 <br/>일상생활에 지장없음</p></li>
</ul>
</div>
</section>
<section class="content3">
<div class="inner_wrap">
<h3><span>특징 </span>Unique</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>인젝터 사용으로 통증은 줄어들고 시술시간은 단축</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>피부 상태에 따른 맞춤형 스킨부스터 시술</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>친수성의 안전한 인체 구성물질, 하이드로 밸런스 복원</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>피부 수분유지와 탄력을 높이는 리프팅</p>
</li>
</ul>
</div>
</section>
<section class="content4">
<div class="inner_wrap">
<h3><span>시술횟수 </span>Time</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/time.png" alt="check"/></div>
<p>2~4주 간격으로 3~5회</p>
</li>
</ul>
</div>
</section>
<section class="content5">
<div class="inner_wrap">
<h3><span>주의사항 </span>Notice</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/notice.png" alt="check"/></div>
<p>
시술한 당일에는 샤워를 금해주시기를 바랍니다.<br/>
개인의 특성에 따라 붓기가 생길수 있습니다.<br/>
시술 부위를 누르거나 문지르는 등 강한 자극은 피합니다.<br/>
시술 후 일주일동안은 흡연, 음주를 삼갑니다.<br/>
통증이 시술 직후보다 더 심해지시면 의원에 즉시 연락!
</p>
</li>
</ul>
</div>
</section>
</div>
<!-- 웰빙주사 -->
<div id="wellbeing"></div>
</main>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
</th:block>
</html>

View File

@@ -0,0 +1,232 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/petit/petitFillerSelect.css?v1.0">
</th:block>
<th:block layout:fragment="layoutContent">
<div class="same">
<aside>
<ul>
<li class="first"><a href="#ellanse">엘란쎄</a></li>
<li><a href="#sculptra">스컬트라</a></li>
</ul>
</aside>
<main>
<!-- 엘란쎄 -->
<div id="ellanse">
<section class="main_img">
<img class="pc" src="/image/web/petit_main2.jpg" alt="diet"/>
<img class="mb" src="/image/web/Mpetit_main2.jpg" alt="diet"/>
<div class="text_box">
<div class="left_text_box">
<p class="sub_title">콜라겐 필러</p>
<p class="title">엘란쎄</p>
<p class="sub_text">
PCL성분으로 유지기간이<br class="mb"/> 2~4년 되는 <br class="pc"/>
오래가는 콜라겐 필러! <br class="mb"/>자연스러운 <br class="pc"/>
볼륨 효과와 <br class="mb"/>HA필러의 단점을 보완!
</p>
</div>
</div>
</section>
<section class="content1">
<div class="inner_wrap">
<p class="title">콜라겐 필러 엘란쎄</p>
<p class="sub_title">메이드유 엘란쎄 시술은 <br class="mb"/>국내 최다 16,000시린지 달성 시술병원</p>
<p class="sub_text">
콜라겐을 유발 자기살채움으로 자연스럽게 유지되는 볼륨형성되며 HA필러의 단점인 <br class="pc"/>울퉁불퉁현상, 틴들현상, 경계감, 이물감이 거의 없는 필러
엘란쎄 <span>M 2년</span>유지 엘란쎄 <span>E 4년</span> 유지
</p>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<h3><span>시술효과 </span>Effect</h3>
<ul>
<li><p>2013년 9월 ~ <br/>현시점까지 <br/>엘란쎄 누적 사용량<br/> 1등 병원</p></li>
<li><p>풍부한 시술 <br/>경험으로 예측 <br/>가능한 시술결과</p></li>
<li><p>원하는 디자인으로 <br/>시술 가능, 시술후 <br/>에도 교정 가능</p></li>
<li><p>합리적인 비용으로 <br/>성형수술에 비해 <br/>비용이 저렴</p></li>
</ul>
</div>
</section>
<section class="content3">
<div class="inner_wrap">
<h3><span>특징 </span>Unique</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>즉각적인 콜라겐 볼륨업 - </span>자가 콜라겐생성으로 자연스러움</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>오랜 지속기간 - </span>2년간 유지시키는 볼륨효과</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>HA필러와 차별화 - </span>이동, 경계감, 틴들현상 없는 볼륨</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>일상생활 OK 붓기 멍 최소화 - </span>캐뉼라 사용으로 다운타임 최소화</p>
</li>
</ul>
</div>
</section>
<section class="content4">
<div class="inner_wrap">
<h3><span>시술횟수 </span>Time</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/time.png" alt="check"/></div>
<p>의료진의 판단에 따라</p>
</li>
</ul>
</div>
</section>
<section class="content5">
<div class="inner_wrap">
<h3><span>주의사항 </span>Notice</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/notice.png" alt="check"/></div>
<p>
붓기, 멍, 약간 가려운 현상은 사라지며, 과격한 세안 조심!<br/>
시술 후 부위가 심한 저온 또는 고온에 노출되지 않게 조심!<br/>
주사부위 마사지나 뜨거운 사우나, 심한운동은 7일간 조심!<br/>
하루 이상 통증 지속, 알러지 현상 나타나면 병원으로 내원!
</p>
</li>
</ul>
</div>
</section>
</div>
<!-- 스컬트라 -->
<div id="sculptra">
<section class="main_img">
<img class="pc" src="/image/web/petit_main2_2.jpg" alt="diet"/>
<img class="mb" src="/image/web/Mpetit_main2_2.jpg" alt="diet"/>
<div class="text_box">
<div class="left_text_box">
<p class="sub_title">피부, 속부터 채우다.</p>
<p class="title">스컬트라</p>
<p class="sub_text">
PLLA성분으로 구성된 콜라겐 촉진제 <br/>
볼륨을 채워주며 시간이 지날수록 <br/>
더욱 자연스러운 볼륨효과를!
</p>
</div>
</div>
</section>
<section class="content1">
<div class="inner_wrap">
<p class="title">콜라겐 볼륨 스컬트라</p>
<p class="sub_title">PLLA성분으로 구성된 콜라겐 촉진제 볼륨을 채워주며 시간이 지날수록 더욱 자연스러운 볼륨효과를!</p>
<p class="sub_text">
나이가 들어 탄력을 잃은 콜라겐을 촉진하고 강력하게 재생시켜 볼륨을 채워주는 방식으로 다른 물질이 아닌 본인의 체내성분으로
채워올리기 때문에 안전하며 시간이 지날수록 더욱 볼륨효과를 높여주는 신개념 동안 시스템입니다.
</p>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<h3><span>시술효과 </span>Effect</h3>
<ul>
<li><p>스컬트라 <br/>6,000vial <br/>돌파 병원</p></li>
<li><p>풍부한 시술 <br/>경험으로 예측 <br/>가능한 시술결과</p></li>
<li><p>원하는 디자인으로 <br/>시술 가능, 시술후 <br/>에도 교정 가능</p></li>
<li><p>합리적인 비용으로 <br/>성형수술에 비해 <br/>비용이 저렴</p></li>
</ul>
</div>
</section>
<section class="content3">
<div class="inner_wrap">
<h3><span>특징 </span>Unique</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>콜라겐 볼륨업 - </span>자가 콜라겐 생성으로 자연스러움</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>오랜 지속기간 - </span>2년간 유지시키는 볼륨효과</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>HA필러와 차별화 - </span>이동, 경계감, 틴들현상 없는 볼륨</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>일상생활 OK 붓기 멍 최소화 - </span>캐뉼라 사용으로 다운타임 최소화</p>
</li>
</ul>
</div>
</section>
<section class="content4_1">
<div class="inner_wrap">
<h3><span>노하우</span> Know-how <span>3*3*3</span> SYSTEM</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/knowhow.png" alt="check"/></div>
<p>
<span>3S시술전<br/>
3S시술전 통증, 멍 완화를 위한 메이드유만의 3가지 마취법</span><br/>
피부마취 : 마취 연고를 통한 1단계 피부마취<br/>
신경마취 : 신경주사를 통한 2단계 신경마취<br/>
메이드유마취 : 메이드유 주사를 통한 3단계 마취<br/>
<br/>
<span>3S시술 3S<br/>
시술 중 통증, 멍 완화를 위한 3가지 시술법</span><br/>
카테터 : 블런트 특수 카테터를 이용<br/>
나노니들 : 미세주사바늘을 이용<br/>
신의 손 : 메이드유 원장만의 노하우를 이용<br/>
<br/>
<span>3S시술 후 3S <br/>
시술 후 통증, 멍 완화를 위한 메이드유만의 3가지 진정법</span><br/>
크리이오 냉각테라피 : 크라이오 냉각테라피로 진정<br/>
진정 재생 관리 : 재생팩으로 피부진정, 재생<br/>
진정재생레이저 : 스마트룩스로 피부진정, 재생
</p>
</li>
</ul>
</div>
</section>
<section class="content4">
<div class="inner_wrap">
<h3><span>시술횟수 </span>Time</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/time.png" alt="check"/></div>
<p>최소 3회 이상</p>
</li>
</ul>
</div>
</section>
<section class="content5">
<div class="inner_wrap">
<h3><span>주의사항 </span>Notice</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/notice.png" alt="check"/></div>
<p>
붓기, 주사주위 멍, 약간의 가려운 현상은 자연스럽게 사라지며, 과격한 세안은 조심!<br/>
시술 후, 시술 부위가 너무 심한 저온 또는 고온에 노출되지 않게 조심해주세요.<br/>
주사부위의 마사지나 뜨거운 사우나, 심한 운동은 7일 정도 피하세요.<br/>
주사부위가 하루이상 통증이 계속 되거나, 알러지 현상이 나타나면 병원으로 내원!<br/>
스컬트라의 고른 분포를 위해 얼굴 중 뼈가 두드러진 부위를 빈틈없이 마사지!<br/>
5·5·5 Rule : 5일간, 하루에 5회, 5분동안 치료부위를 마사지!
</p>
</li>
</ul>
</div>
</section>
</div>
</main>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
</th:block>
</html>

View File

@@ -0,0 +1,158 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/petit/petitLaserSelect.css?v1.0">
<style>
@media (min-width: 769px) {
/* ====== 공통 레이아웃: 헤더 이후 aside/메인 정렬 및 다이어트 처방약 링크 ====== */
.project_wrap .same {
display: flex;
margin-top: 85px; /* header 높이만큼 아래로 */
margin-left: auto;
margin-right: auto;
box-sizing: border-box;
}
.project_wrap .same aside {
width: 200px;
min-width: 200px;
background: url('/image/web/aside.jpg') repeat-y;
position: fixed;
top: 85px; /* header 높이만큼 아래로 */
left: 0;
height: 100vh;
z-index: 10;
}
.project_wrap .same aside ul {
position: static;
top: auto;
left: auto;
margin-top: 30px;
}
.project_wrap .same main {
width: 1080px;
min-width: 0;
position: relative;
margin-left: 200px;
}
.first {
float: right;
padding-right: 10px;
}
.project_wrap .same aside ul li a {
margin-top: 50px;
}
}
/* ====== END ====== */
</style>
</th:block>
<th:block layout:fragment="layoutContent">
<div class="same inner_wrap">
<aside>
<ul>
<li class="first"><a href="#shurink">슈링크<br/>(더블로 골드)</a></li>
</ul>
</aside>
<main>
<div id="shurink">
<section class="main_img">
<img class="pc" src="/image/web/petit_main1.jpg" alt="diet"/>
<img class="mb" src="/image/web/Mpetit_main1.jpg" alt="diet"/>
<div class="text_box">
<div class="left_text_box">
<p class="sub_title">약해진 얼굴의 SMAS(피부근막)층을 강화!</p>
<p class="title">SHURINK</p>
<p class="sub_text">
늘어진 피부를 탄력있게<br class="mb"/> 바꿔주는 슈링크!<br/>
고강도 집속 초음파를 통한<br class="mb"/> 즉각적인 효과
</p>
</div>
</div>
</section>
<section class="content1">
<div class="inner_wrap">
<p class="title">슈링크·더블로골드</p>
<p class="sub_title">노화로 인해 약해진 얼굴의 SMAS(피부근막)층을 강화시켜 피부를 탄력있게 바꾸어주는 시술!</p>
<p class="sub_text">
핫한 TV속 화제의 레이저리프팅 작아지고 탄탄해지는 V라인 & 작은얼굴 리프팅! 일반레이저가 침투하지 못하는
피부속 1.5~4.5mm 깊이게 정확학 강한 초음파 에너지를 집중시켜 피부를 리프팅 하는 시술입니다.
HIFU (고강도 직접 초음파 )를 통하여 진피층과 피부 처짐의 원인인 근막층에 즉각적인 리프팅 & 주름개선 효과를 얻을 수 있는 시술입니다.
</p>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<h3><span>시술효과 </span>Effect</h3>
<ul>
<li><p>비수술 <br/>비절개 방식의 시술</p></li>
<li><p>치료 부위를 <br/>모니터로 확인 가능</p></li>
<li><p>진피층, 근막층까지 <br/>두 개층을 <br/>동시에 치료</p></li>
<li><p>빠른 시술 시간 <br/>(약 30분 소요) <br/>시술 직후 바로 <br/>일상 생활 가능</p></li>
</ul>
</div>
</section>
<section class="content3">
<div class="inner_wrap">
<h3><span>특징 </span>Unique</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>일반레이저가 침투하지 못하는 피부속까지 가능한 HIFU리프팅</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>1.5 ~ 4.5mm 깊이에 정확하고 강한 초음파 에너지 집중</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>피부조직이 응고, 수축되어 당김현상이 나타나는 리프팅</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>노화로 인해 약해진 얼굴의 SMAS층을 강화시켜, 탄력있게!</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>콜라겐이 진피층 및 피부지방 아래의 깊은 근막층까지 전달!</p>
</li>
</ul>
</div>
</section>
<section class="content4">
<div class="inner_wrap">
<h3><span>시술횟수 </span>Time</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/time.png" alt="check"/></div>
<p>의료진의 판단에 따라</p>
</li>
</ul>
</div>
</section>
<section class="content5">
<div class="inner_wrap">
<h3><span>주의사항 </span>Notice</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/notice.png" alt="check"/></div>
<p>
시술한 당일에는 샤워를 금해주시기를 바랍니다.<br/>
개인의 특성에 따라 붓기가 생길수 있습니다.<br/>
시술 부위를 누르거나 문지르는 등 강한 자극은 피합니다.<br/>
시술 후 일주일동안은 흡연, 음주를 삼갑니다.<br/>
통증이 시술 직후보다 더 심해지시면 의원에 즉시 연락!
</p>
</li>
</ul>
</div>
</section>
</div>
</main>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
</th:block>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,408 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 전체 기본 스타일 */
html, body {
height: 100vh;
margin: 0;
padding: 0;
font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
background-color: #f8f9fa;
color: #1a1a1a;
line-height: 1.6;
overflow-x: hidden;
font-size: 16px;
}
/* 메인 컨테이너 */
.container {
max-width: 1280px;
width: 100%;
height: calc(100vh - 300px); /* 헤더/푸터 공간 확보 */
min-height: calc(100vh - 300px);
margin: 0 auto;
box-sizing: border-box;
display: flex;
flex-direction: column;
gap: 1.5rem;
}
/* 상단 헤더 영역 */
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background: white;
border-radius: 16px;
box-shadow: 0 2px 16px rgba(0,0,0,0.06);
border-bottom: 3px solid #C60B24;
flex-shrink: 0;
}
.page-title {
font-size: clamp(1.5rem, 3vw, 1.875rem); /* 24px ~ 30px */
font-weight: 600;
color: #1a1a1a;
margin: 0;
letter-spacing: -0.025em;
}
/* 하단 메인 콘텐츠 영역 (사이드바 + 메인) */
.content-wrapper {
flex: 1;
display: flex;
gap: 1.5rem;
min-height: 0;
}
/* 좌측 카테고리 사이드바 */
.sidebar {
width: 280px;
min-width: 250px;
flex-shrink: 0;
background: white;
border-radius: 16px;
box-shadow: 0 2px 16px rgba(0,0,0,0.06);
height: fit-content;
max-height: 100%;
overflow-y: auto;
position: sticky;
top: 0;
}
.sidebar-header {
padding: 1.25rem 1.5rem;
border-bottom: 1px solid #e9ecef;
font-size: 1.125rem; /* 18px */
font-weight: 600;
color: #374151;
}
.category-list {
list-style: none;
padding: 1rem;
}
.category-item {
margin-bottom: 0.375rem;
}
.category-link {
display: block;
padding: 0.875rem 1rem;
text-decoration: none;
color: #6b7280;
border-radius: 10px;
transition: all 0.2s ease;
border: 1px solid transparent;
cursor: pointer;
font-size: 0.95rem; /* 15.2px */
font-weight: 500;
}
.category-link:hover {
background-color: #f9fafb;
color: #C60B24;
border-color: #f3f4f6;
transform: translateX(2px);
}
.category-link.active {
background-color: rgba(198, 11, 36, 0.08);
color: #C60B24;
border-color: #C60B24;
border-left: 4px solid #C60B24;
font-weight: 600;
}
/* 메인 콘텐츠 영역 */
.main-content {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
height: 100%;
}
/* 스크롤 가능한 서비스 카드 컨테이너 */
.services-list {
flex: 1;
overflow-y: auto;
padding-right: 0.5rem;
min-height: 0;
}
.services-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
gap: 1.25rem;
padding-bottom: 2rem;
}
.service-card {
background: white;
border-radius: 16px;
padding: 1.75rem;
box-shadow: 0 2px 16px rgba(0,0,0,0.06);
transition: all 0.3s ease;
border: 1px solid #f1f5f9;
}
.service-card:hover {
transform: translateY(-6px);
box-shadow: 0 8px 32px rgba(0,0,0,0.12);
border-color: #C60B24;
}
.service-title {
font-size: 1.375rem; /* 22px */
font-weight: 600;
color: #1a1a1a;
margin-bottom: 0.5rem;
letter-spacing: -0.025em;
}
.service-description {
color: #6b7280;
margin-bottom: 1rem;
line-height: 1.5;
font-size: 0.9375rem; /* 15px */
}
.service-price {
font-size: 1.5rem; /* 24px */
font-weight: 700;
color: #C60B24;
text-align: right;
}
.cancel-price {
font-size: 1.125rem; /* 18px */
font-weight: 400;
color: #9ca3af;
text-align: right;
text-decoration: line-through;
}
/* 로딩 스타일 */
.loading {
text-align: center;
padding: 2rem;
color: #6b7280;
font-size: 0.9375rem; /* 15px */
}
.error-message {
text-align: center;
padding: 2rem;
color: #dc2626;
font-size: 0.9375rem; /* 15px */
}
/* 스크롤바 커스텀 스타일링 */
.services-list::-webkit-scrollbar,
.sidebar::-webkit-scrollbar {
width: 6px;
}
.services-list::-webkit-scrollbar-track,
.sidebar::-webkit-scrollbar-track {
background: #f8fafc;
border-radius: 3px;
}
.services-list::-webkit-scrollbar-thumb,
.sidebar::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 3px;
}
.services-list::-webkit-scrollbar-thumb:hover,
.sidebar::-webkit-scrollbar-thumb:hover {
background: #C60B24;
}
/* 반응형 디자인 */
@media (max-width: 1024px) {
.container {
max-width: 100%;
padding: 1rem;
gap: 1rem;
}
.sidebar {
width: 240px;
min-width: 220px;
}
.services-grid {
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 1rem;
}
.header {
padding: 1.25rem 1.5rem;
}
.page-title {
font-size: clamp(1.375rem, 2.8vw, 1.75rem); /* 22px ~ 28px */
}
}
@media (max-width: 768px) {
.container {
flex-direction: column;
padding: 1rem;
gap: 1rem;
height: auto;
min-height: calc(100vh - 300px);
}
.content-wrapper {
flex-direction: column;
gap: 1rem;
}
.sidebar {
width: 100%;
position: static;
order: 1;
flex-shrink: 0;
max-height: none;
}
.category-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 0.5rem;
padding: 1rem;
}
.category-link {
text-align: center;
padding: 0.75rem 0.5rem;
font-size: 0.875rem; /* 14px */
}
.main-content {
order: 2;
flex: 1;
height: auto;
min-height: 0;
}
.services-grid {
grid-template-columns: 1fr;
gap: 1rem;
}
.header {
padding: 1rem 1.5rem;
border-radius: 12px;
}
.page-title {
font-size: clamp(1.25rem, 2.5vw, 1.5rem); /* 20px ~ 24px */
}
.service-title {
font-size: 1.25rem; /* 20px */
}
.service-price {
font-size: 1.375rem; /* 22px */
}
}
@media (max-width: 480px) {
.container {
padding: 0.75rem;
}
.header {
padding: 0.875rem 1rem;
}
.page-title {
font-size: clamp(1.125rem, 2.2vw, 1.375rem); /* 18px ~ 22px */
}
.sidebar-header {
font-size: 1rem; /* 16px */
padding: 1rem 1.25rem;
}
.service-card {
padding: 1.25rem;
}
}
</style>
</th:block>
<th:block layout:fragment="layout_top_script">
<script th:inline="javascript">
// 서버에서 전달받은 파라미터들을 전역 변수로 설정
window.pageParams = {
categoryDivCd: /*[[${param.categoryDivCd}]]*/ '',
categoryNo: /*[[${param.categoryNo}]]*/ ''
};
// 빈 값 처리
if (!window.pageParams.categoryDivCd || window.pageParams.categoryDivCd === 'null') {
window.pageParams.categoryDivCd = 'SERVICE'; // 기본값
}
if (!window.pageParams.categoryNo || window.pageParams.categoryNo === 'null') {
window.pageParams.categoryNo = '';
}
console.log('페이지 파라미터:', window.pageParams);
</script>
</th:block>
<th:block layout:fragment="layoutContent">
<div class="container">
<!-- 상단 헤더 영역 -->
<div class="header">
<h2 class="page-title">시술안내/가격</h2>
</div>
<!-- 하단 콘텐츠 영역 (사이드바 + 메인) -->
<div class="content-wrapper">
<!-- 좌측 카테고리 사이드바 -->
<aside class="sidebar">
<div class="sidebar-header">Category</div>
<ul class="category-list" id="category-list">
<li class="category-item">
<div class="loading">카테고리 로딩 중...</div>
</li>
</ul>
</aside>
<!-- 메인 콘텐츠 -->
<main class="main-content">
<!-- 스크롤 가능한 서비스 카드 컨테이너 -->
<div class="services-list">
<div class="services-grid" id="services-grid">
<div class="loading">서비스 정보 로딩 중...</div>
</div>
</div>
</main>
</div>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
<script src="/js/web/service/serviceInfo.js"></script>
</th:block>
</html>

View File

@@ -0,0 +1,782 @@
<!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="~{/web/layout/layout}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<th:block layout:fragment="layoutCss">
<!-- Choices.js CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/choices.js/10.2.0/choices.min.css" />
<style>
* { box-sizing: border-box; }
body {
font-family: 'Noto Sans KR', sans-serif;
margin: 0;
background: #f7f7f9;
color: #222;
}
#service-header {
background: #fff;
border-bottom: 1px solid #ececec;
padding: 14px 0 14px 24px;
font-size: 0.98em;
color: #888;
}
.main-wrap {
max-width: 1280px;
margin: 0 auto;
background: #fff;
border-radius: 18px;
box-shadow: 0 2px 12px rgba(0,0,0,0.07);
margin-top: 32px;
padding: 0 0 32px 0;
}
.top-section {
display: flex;
flex-wrap: wrap;
gap: 32px;
padding: 32px 32px 0 32px;
align-items: flex-start;
}
.img-box {
border-radius: 18px;
align-items: center;
justify-content: center;
overflow: hidden;
}
.img-box img {
width: 100%;
object-fit: cover;
border-radius: 18px;
}
.info-box {
flex: 1 1 300px;
min-width: 240px;
}
.info-title {
font-size: 1.7em;
font-weight: 700;
margin-bottom: 6px;
color: #222;
}
.info-desc {
color: #444;
font-size: 1.1em;
margin-bottom: 18px;
}
.info-price {
font-size: 1.2em;
font-weight: 700;
color: #b23c3c;
margin-bottom: 18px;
}
.select-row {
margin-bottom: 18px;
}
.select-row label {
font-weight: 500;
margin-bottom: 8px;
display: block;
}
.total-row {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 1.1em;
margin-bottom: 18px;
}
.total-row .total-label {
color: #888;
}
.total-row .total-price {
font-weight: bold;
color: #b23c3c;
}
.reserve-btn {
width: 100%;
padding: 14px 0;
background: #b23c3c;
color: #fff;
border: none;
border-radius: 8px;
font-size: 1.1em;
font-weight: bold;
cursor: pointer;
transition: background 0.15s;
}
.reserve-btn:disabled {
background: #ddd;
color: #888;
cursor: not-allowed;
}
.desc-section {
margin-top: 36px;
padding: 0 32px;
}
.desc-title {
font-size: 1.25em;
font-weight: 700;
margin-bottom: 12px;
color: #222;
}
.desc-content {
color: #444;
font-size: 1.05em;
line-height: 1.7;
margin-bottom: 20px;
}
.hashtag-section {
margin-top: 30px;
padding: 20px 0;
border-top: 1px solid #eee;
}
.hashtag-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.hashtag-list {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.hashtag {
display: inline-block;
background-color: #f8f9fa;
color: #495057;
padding: 8px 15px;
border-radius: 20px;
font-size: 14px;
text-decoration: none;
border: 1px solid #dee2e6;
transition: all 0.3s ease;
}
.hashtag:hover {
background-color: #007bff;
color: white;
border-color: #007bff;
cursor: pointer;
}
#thumbnail-bottom-txt{
padding: 8px;
margin-top: 10px;
background-color: #fff;
}
/* Choices.js 커스터마이징 - 개선된 버전 */
.choices {
border: 1px solid #ddd !important;
border-radius: 6px !important;
font-size: 1em !important;
background: #fff !important;
min-width: 300px !important;
}
.choices__inner {
background: #fff !important;
padding: 8px 12px !important;
min-height: 40px !important;
color: #222 !important;
min-width: 280px !important;
width: 100% !important;
}
/* 플레이스홀더 텍스트 잘림 방지 - 핵심 수정 */
.choices__placeholder {
color: #888 !important;
opacity: 1 !important;
width: 100% !important;
min-width: 200px !important;
white-space: nowrap !important;
overflow: visible !important;
text-overflow: clip !important;
display: block !important;
}
.choices__input {
color: #222 !important;
background: transparent !important;
min-width: 200px !important;
width: 100% !important;
}
.choices__input::placeholder {
color: #888 !important;
opacity: 1 !important;
width: 100% !important;
min-width: 200px !important;
white-space: nowrap !important;
overflow: visible !important;
}
/* 다중 선택시 입력 필드 너비 확보 */
.choices[data-type*="select-multiple"] .choices__input {
min-width: 200px !important;
width: auto !important;
flex: 1 !important;
}
/* 선택된 항목들과 입력 필드 공간 분배 */
.choices__list--multiple {
/* display: flex !important; */
flex-wrap: wrap !important;
align-items: center !important;
}
.choices__list--multiple:empty + .choices__input {
min-width: 200px !important;
width: 100% !important;
flex: 1 !important;
}
/* 선택된 항목의 가격 표시 스타일 - 새로 추가 */
.selected-item-content {
display: flex !important;
flex-direction: column !important;
align-items: flex-start !important;
flex: 1 !important;
}
.selected-item-name {
font-weight: 500 !important;
margin-bottom: 2px !important;
}
.selected-item-price {
font-size: 0.85em !important;
}
.selected-price {
color: #b23c3c !important;
font-weight: bold !important;
}
.selected-price-discount {
color: #b23c3c !important;
font-weight: bold !important;
font-size: 0.9em !important;
}
.selected-price-original {
color: #aaa !important;
font-size: 0.85em !important;
text-decoration: line-through !important;
margin-left: 4px !important;
}
/* 선택된 항목들 스타일 수정 */
.choices__list--multiple .choices__item {
background-color: #f8f9fa !important;
border: 1px solid #dee2e6 !important;
border-radius: 16px !important;
padding: 8px 12px !important;
margin: 2px !important;
font-size: 0.9em !important;
color: #495057 !important;
flex-shrink: 0 !important;
display: flex !important;
align-items: center !important;
/* max-width: 300px !important; */
}
/* 빨간색으로 변경 */
.choices__button {
background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjYjIzYzNjIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==') !important;
background-size: 14px 14px !important;
background-position: center !important;
background-repeat: no-repeat !important;
border-left:0 !important;
margin:0 !important;
padding:0 !important;
width:14px !important;
}
/* 드롭다운 컨테이너 */
.choices__list--dropdown {
background: #fff !important;
border: 1px solid #ddd !important;
border-radius: 6px !important;
box-shadow: 0 2px 8px rgba(0,0,0,0.1) !important;
}
/* 드롭다운 옵션들 스타일 */
.choices__list--dropdown .choices__item {
padding: 8px 12px !important;
display: flex !important;
justify-content: space-between !important;
align-items: center !important;
color: #222 !important;
}
.choices__list--dropdown .choices__item--selectable:hover {
background-color: #f5f5f5 !important;
color: #222 !important;
}
.choices__list--dropdown .choices__item--highlighted {
background-color: #b23c3c !important;
color: #fff !important;
}
/* 포커스 상태 */
.choices.is-focused .choices__inner {
border-color: #b23c3c !important;
}
/* 가격 표시 스타일 */
.procedure-price {
color: #b23c3c !important;
font-weight: bold !important;
font-size: 0.9em !important;
}
.procedure-price-discount {
color: #b23c3c !important;
font-weight: bold !important;
font-size: 0.9em !important;
}
.procedure-price-original {
color: #aaa !important;
font-size: 0.85em !important;
text-decoration: line-through !important;
margin-left: 4px !important;
}
/* 드롭다운이 열렸을 때 하이라이트된 항목의 가격 색상 */
.choices__list--dropdown .choices__item--highlighted .procedure-price,
.choices__list--dropdown .choices__item--highlighted .procedure-price-discount {
color: #fff !important;
}
.choices__list--dropdown .choices__item--highlighted .procedure-price-original {
color: #ddd !important;
}
/* 검색 입력창 스타일 */
.choices[data-type*="select-multiple"] .choices__input {
background-color: transparent !important;
color: #222 !important;
}
/* 비활성화 상태 */
.choices.is-disabled .choices__inner {
background-color: #f8f9fa !important;
color: #6c757d !important;
cursor: not-allowed !important;
}
/* 반응형 대응 */
@media (max-width: 600px) {
.choices {
min-width: 250px !important;
}
.choices__inner {
min-width: 230px !important;
}
.choices__placeholder,
.choices__input,
.choices__input::placeholder {
min-width: 150px !important;
}
.choices__list--multiple .choices__item {
max-width: 250px !important;
padding: 6px 10px !important;
}
.selected-item-name {
font-size: 0.9em !important;
}
.selected-item-price {
font-size: 0.8em !important;
}
.choices__list--multiple .choices__item[data-deletable] .choices__button {
width: 20px !important;
height: 20px !important;
font-size: 16px !important;
text-indent: 0 !important;
}
}
@media (max-width: 900px) {
.main-wrap { margin-top: 16px; }
.top-section { flex-direction: column; gap: 18px; padding: 20px 10px 0 10px; }
.img-box { width: 100%;}
.info-box { min-width: unset; }
.desc-section { padding: 0 10px; }
}
@media (max-width: 600px) {
.main-wrap { margin-top: 0; border-radius: 0; box-shadow: none; }
.top-section { padding: 12px 2vw 0 2vw; }
.desc-section { padding: 0 2vw; }
}
</style>
</th:block>
<th:block layout:fragment="layout_top_script">
<script th:inline="javascript">
let category_div_cd = [[${CATEGORY_DIV_CD}]];
let category_no = [[${CATEGORY_NO}]];
let post_no = [[${POST_NO}]];
const CDN_URL = [[${@environment.getProperty('url.cdn')}]];
</script>
</th:block>
<th:block layout:fragment="layoutContent">
<div id="service-header">
시술안내/가격 &nbsp;&gt;&nbsp; <span id="header-category-nm"></span> &nbsp;&gt;&nbsp; <span id="header-title"></span>
</div>
<div class="main-wrap">
<div class="top-section">
<div class="img-box">
<img id="serviceThumb" th:src="${@environment.getProperty('madeu.logo.size800x450')}" alt="썸네일 이미지">
<pre id="thumbnail-bottom-txt"></pre>
</div>
<div class="info-box">
<div class="info-title" id="title">메쉬다 D/S</div>
<div class="info-desc" id="contents">전신 라인 정리에 특화된 메쉬다 바디주사!</div>
<div class="hashtag-section">
<div class="hashtag-container">
<div class="hashtag-list">
<span class="hashtag">#메쉬다바디주사</span>
<span class="hashtag">#쥬베룩</span>
<span class="hashtag">#바디라인정리</span>
<span class="hashtag">#콜라겐부스터</span>
<span class="hashtag">#전신시술</span>
<span class="hashtag">#자연스러운볼륨</span>
<span class="hashtag">#빠른회복</span>
<span class="hashtag">#합리적가격</span>
</div>
</div>
</div>
<div class="info-price"><span id="price">0</span>원 부터</div>
<div class="select-row">
<label for="procedure-select">시술 선택</label>
<select id="procedure-select" multiple></select>
</div>
<div class="total-row">
<span class="total-label">총 금액</span>
<span class="total-price" id="total">0원</span>
</div>
<button class="reserve-btn" id="reserve-btn" disabled>시술 예약하기</button>
</div>
</div>
<div class="desc-section">
<div class="desc-content">
<img id="contents_path" th:src="${@environment.getProperty('madeu.logo.size800x450')}" alt="컨텐츠 이미지" width="100%" />
</div>
</div>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
<!-- Choices.js JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/choices.js/10.2.0/choices.min.js"></script>
<script>
// 전역 변수
let procedureChoices;
let priceList = [];
const totalEl = document.getElementById('total');
const reserveBtn = document.getElementById('reserve-btn');
// 초기화
fn_SelectDetail(category_div_cd, category_no, post_no);
/****************************************************************************
* 카테고리 목록 가져오기
****************************************************************************/
function fn_SelectDetail(category_div_cd, category_no, post_no) {
let formData = new FormData();
formData.append('CATEGORY_DIV_CD', category_div_cd);
formData.append('CATEGORY_NO', category_no);
formData.append('POST_NO', post_no);
$.ajax({
url: encodeURI('/webservice/selectServiceDetail.do'),
data: formData,
dataType: 'json',
processData: false,
contentType: false,
type: 'POST',
async: true,
success: function(data) {
if(data.msgCode == '0') {
// 화면 데이터 변경
$('#title').text(data.rows.TITLE);
$('#serviceThumb').attr('src', CDN_URL + data.rows.THUMBNAIL_PATH);
$('#thumbnail-bottom-txt').text(data.rows.THUMBNAIL_BOTTOM_TXT);
$('#contents').text(data.rows.CONTENT);
if(data.rows.PRICE == null || data.rows.PRICE == undefined) {
$('#price').text('0');
} else {
$('#price').text(data.rows.PRICE.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
}
// header 동적 변경
$('#header-category-nm').text(data.rows.CATEGORY_NM);
$('#header-title').text(data.rows.TITLE);
// 해시태그 처리
var hashtagHtml = '';
if (data.rows.HASHTAG) {
var tags = data.rows.HASHTAG.split('#');
tags.forEach(function(tag) {
var trimmed = tag.trim();
if(trimmed) {
hashtagHtml += '<span class="hashtag">#' + trimmed + '</span>';
}
});
}
$('.hashtag-list').html(hashtagHtml);
$('#contents_path').attr('src', CDN_URL + data.rows.CONTENTS_PATH);
// 시술 목록 데이터 처리
updateProcedureOptions(data.price || []);
} else {
modalEvent.danger("조회 오류", data.msgDesc);
}
},
error: function(xhr, status, error) {
modalEvent.danger("조회 오류", "조회 중 오류가 발생하였습니다. 잠시후 다시시도하십시오.");
},
beforeSend: function() {
$(".loading-image-layer").show();
},
complete: function() {
$(".loading-image-layer").hide();
}
});
}
/****************************************************************************
* Choices.js 초기화 및 옵션 업데이트
****************************************************************************/
function updateProcedureOptions(data) {
priceList = data;
// 기존 Choices 인스턴스 제거
if (procedureChoices) {
procedureChoices.destroy();
}
// 선택 옵션 데이터 생성
const choices = data.map(item => {
if (!item.MU_TREATMENT_PROCEDURE_ID || !item.TREATMENT_PROCEDURE_NAME) return null;
const basePrice = (item.PRICE || 0) + (item.VAT || 0);
const discountPrice = item.DISCOUNT_PRICE;
return {
value: item.MU_TREATMENT_PROCEDURE_ID,
label: item.TREATMENT_PROCEDURE_NAME,
customProperties: {
name: item.TREATMENT_PROCEDURE_NAME,
price: basePrice,
discountPrice: discountPrice,
originalData: item
}
};
}).filter(Boolean);
// Choices.js 초기화
procedureChoices = new Choices('#procedure-select', {
removeItemButton: true,
searchEnabled: true,
searchPlaceholderValue: '시술명으로 검색...',
placeholder: true,
placeholderValue: '시술을 선택하세요',
maxItemCount: -1,
choices: choices,
shouldSort: false,
searchResultLimit: 10,
searchFields: ['label', 'value'],
itemSelectText: '',
noChoicesText: '선택 가능한 시술이 없습니다',
noResultsText: '검색 결과가 없습니다',
loadingText: '시술 정보를 불러오는 중...',
// 템플릿 커스터마이징 - 선택된 항목에 가격 표시 추가
callbackOnCreateTemplates: function(template) {
return {
// 선택된 항목 템플릿 - 가격 정보 포함
item: ({ classNames }, data) => {
const customProps = data.customProperties || {};
const name = customProps.name || data.label;
const price = customProps.price || 0;
const discountPrice = customProps.discountPrice;
// 가격 표시 HTML 생성
let priceHtml = '';
if (discountPrice && discountPrice < price) {
priceHtml = `
<span class="selected-price-discount">${discountPrice.toLocaleString()}원</span>
<span class="selected-price-original">${price.toLocaleString()}원</span>
`;
} else {
priceHtml = `<span class="selected-price">${price.toLocaleString()}원</span>`;
}
return template(`
<div class="${classNames.item} ${data.highlighted ? classNames.highlightedState : classNames.itemSelectable}" data-item data-id="${data.id}" data-value="${data.value}">
<span class="selected-item-content">
<span class="selected-item-name">${name}</span>
<span class="selected-item-price">${priceHtml}</span>
</span>
<button type="button" class="${classNames.button}" aria-label="Remove item: '${data.value}'" data-button>X</button>
</div>
`);
},
// 드롭다운 선택 옵션 템플릿
choice: ({ classNames }, data) => {
const customProps = data.customProperties || {};
const name = customProps.name || data.label;
const price = customProps.price || 0;
const discountPrice = customProps.discountPrice;
let priceHtml = '';
if (discountPrice && discountPrice < price) {
priceHtml = `
<span class="procedure-price-discount">${discountPrice.toLocaleString()}원</span>
<span class="procedure-price-original">${price.toLocaleString()}원</span>
`;
} else {
priceHtml = `<span class="procedure-price">${price.toLocaleString()}원</span>`;
}
return template(`
<div class="${classNames.item} ${classNames.itemChoice} ${data.disabled ? classNames.itemDisabled : classNames.itemSelectable}" data-select-text="" data-choice ${data.disabled ? 'data-choice-disabled aria-disabled="true"' : 'data-choice-selectable'} data-id="${data.id}" data-value="${data.value}">
<div style="display: flex; justify-content: space-between; width: 100%; align-items: center;">
<span>${name}</span>
${priceHtml}
</div>
</div>
`);
}
};
}
});
// 이벤트 리스너 추가
const selectElement = document.getElementById('procedure-select');
selectElement.addEventListener('change', function(event) {
console.log('Selection changed:', event.detail);
updateTotalPrice();
});
selectElement.addEventListener('addItem', function(event) {
console.log('Item added:', event.detail);
updateTotalPrice();
});
selectElement.addEventListener('removeItem', function(event) {
console.log('Item removed:', event.detail);
updateTotalPrice();
});
}
/****************************************************************************
* 총 금액 업데이트 - 개선된 버전
****************************************************************************/
function updateTotalPrice() {
if (!procedureChoices) {
console.log('procedureChoices not initialized');
return;
}
const selectedValues = procedureChoices.getValue(true);
console.log('Selected values:', selectedValues);
let total = 0;
selectedValues.forEach(value => {
const item = priceList.find(p => p.MU_TREATMENT_PROCEDURE_ID == value);
console.log('Found item for value', value, ':', item);
if (item) {
const basePrice = (item.PRICE || 0) + (item.VAT || 0);
const discountPrice = item.DISCOUNT_PRICE;
// 할인가가 있고 더 저렴하면 할인가 사용, 아니면 기본가격 사용
const finalPrice = (discountPrice && discountPrice < basePrice) ? discountPrice : basePrice;
total += finalPrice;
console.log('Added price:', finalPrice);
}
});
console.log('Total calculated:', total);
totalEl.textContent = total.toLocaleString() + '원';
reserveBtn.disabled = selectedValues.length === 0;
}
/****************************************************************************
* 예약 페이지로 이동
****************************************************************************/
function fn_moveReservation(category_div, category_no, post_no) {
if (!procedureChoices) {
alert('시술 선택 기능이 초기화되지 않았습니다.');
return;
}
const selectedValues = procedureChoices.getValue(true);
if (selectedValues.length === 0) {
alert('시술을 선택해주세요.');
return;
}
const form = document.createElement('form');
form.method = 'post';
form.action = '/webservice/selectMakeReservation.do';
// 기본 파라미터 추가
const params = [
{ name: 'CATEGORY_DIV_CD', value: category_div },
{ name: 'CATEGORY_NO', value: category_no },
{ name: 'POST_NO', value: post_no }
];
params.forEach(param => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = param.name;
input.value = param.value;
form.appendChild(input);
});
// 선택된 시술 추가
selectedValues.forEach(value => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'PROCEDURE_ID';
input.value = value;
form.appendChild(input);
});
document.body.appendChild(form);
form.submit();
}
// 예약 버튼 이벤트
reserveBtn.addEventListener('click', function() {
fn_moveReservation(category_div_cd, category_no, post_no);
});
</script>
</th:block>
</html>

View File

@@ -0,0 +1,104 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
</th:block>
<th:block layout:fragment="layoutContent">
<div class="same">
<aside>
<ul>
<li class="first"><a href="#lavieen">프락셀라비앙</a></li>
</ul>
</aside>
<main>
<div id="lavieen">
<section class="main_img">
<img class="pc" src="/image/web/skin_main1.jpg" alt="diet"/>
<img class="mb" src="/image/web/Mskin_main1.jpg" alt="diet"/>
</section>
<section class="content1">
<div class="inner_wrap">
<p class="title">프락셀라비앙</p>
<p class="sub_title">모공 흉터를 개선하는 프리미엄 프락셀 레이저</p>
<p class="sub_text">
프락셀라비앙은 진피층에 콜라겐 합성을 촉진하며 단기간에 적은 횟수로 모공 흉터 및 탄력까지 개선되는 레이저입니다.
1,927nm의 툴리움 레이저 빔을 미세하게 나누어 조사하며 각질층에 미세한 딱지가 탈락되면서 색소가 치료되고 모공 흉터 및 탄력까지 개선됩니다.
</p>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<h3><span>시술효과 </span>Effect</h3>
<ul>
<li><p>모공축소 및 <br/>피부재생</p></li>
<li><p>여드름 및 <br/>위축성 <br/>흉터</p></li>
<li><p>잔주름 및 <br/>탄력개선</p></li>
</ul>
</div>
</section>
<section class="content3">
<div class="inner_wrap">
<h3><span>특징 </span>Unique</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>적은 통증 - </span>미세 빔 방식의 레이저로 시술 중 통증 적음</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>빠른 회복 - </span>시술 후 적극적인 진정관리로 홍조, 딱지 최소화</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>다양한 치료 - </span>빔사이즈의 자유로운 조절로 다양한 흉터 치료</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>복합 치료 - </span>도트, 박리술 등 흉터치료법을 병용하여 효과적</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>새로운 콜라겐과 엘라스틴 생성으로 피부 노화를 개선</span></p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>피부표면에서 피부 결과 피부톤을 개선</span></p>
</li>
</ul>
</div>
</section>
<section class="content4">
<div class="inner_wrap">
<h3><span>시술횟수 </span>Time</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/time.png" alt="check"/></div>
<p>4~6주간격으로 5~10회 시술</p>
</li>
</ul>
</div>
</section>
<section class="content5">
<div class="inner_wrap">
<h3><span>주의사항 </span>Notice</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/notice.png" alt="check"/></div>
<p>
시술 강도, 피부상태에 따라 시술 직후 일시적 홍반 발생<br/>
시술 후 자가세안이나 화장이 가능<br/>
일상생활에 지장이 없음
</p>
</li>
</ul>
</div>
</section>
</div>
</main>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
</th:block>
</html>

View File

@@ -0,0 +1,97 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
</th:block>
<th:block layout:fragment="layoutContent">
<div class="same">
<aside>
<ul>
<li class="first"><a href="#allegro">알레그로</a></li>
</ul>
</aside>
<main>
<div id="allegro">
<section class="main_img">
<img class="pc" src="/image/web/skin_main2.jpg" alt="diet"/>
<img class="mb" src="/image/web/Mskin_main2.jpg" alt="diet"/>
</section>
<section class="content1">
<div class="inner_wrap">
<p class="title">알레그로 레이저</p>
<p class="sub_title">알레그로 레이저의 1450nm 파장은<br class="mb"/> 피부속 물과 기름에 대한 흡수도가 높은 파장입니다.</p>
<p class="sub_text">
1450nm 파장으로 피지선과 반응하여 과도한 피지 분비 감소 및 여드름, 혈관, 홍조, 여드름 붉은 자국 치료 레이저! 피부 진피의 지방성분인 피지선과 반응하여 과도한 피지 분비를 줄여주고,
여드름 붉은 자국을 개선시켜 줍니다. 진피의 물과 반응하여 열에너지로 변환되어 주변 콜라겐 재생을 촉진시켜 모공 수축, 탄력개선, 흉터완화 등에 효과적인 치료입니다.
</p>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<h3><span>시술효과 </span>Effect</h3>
<ul>
<li><p>피지분비 감소</p></li>
<li><p>피부탄력 및 리프팅</p></li>
<li><p>모공 축소</p></li>
<li><p>여드름균과 <br/>염증성 여드름 개선</p></li>
</ul>
</div>
</section>
<section class="content3">
<div class="inner_wrap">
<h3><span>특징 </span>Unique</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span> 물과 기름에 잘 흡수 - </span>피지감소, 모공축소, 여드름 개선!</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span> 피지선에 작용, 여드름 개선 - </span>염증성, 화농성 여드름 개선!</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>간편한 당일 시술, 당일 세안 및 화장 가능 - </span>시술 이후 특별히 관리 및 치료 없이, 바로 일상생활 가능</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>자극이 적고 타 시술과 병행 가능 - </span>다른 약물치료 병행 가능</p>
</li>
</ul>
</div>
</section>
<section class="content4">
<div class="inner_wrap">
<h3><span>시술횟수 </span>Time</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/time.png" alt="check"/></div>
<p>2주 간격으로 5~10회 시술</p>
</li>
</ul>
</div>
</section>
<section class="content5">
<div class="inner_wrap">
<h3><span>주의사항 </span>Notice</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/notice.png" alt="check"/></div>
<p>
시술 강도, 피부상태에 따라 시술 직후 일시적 홍반 발생<br/>
시술 후 자가세안이나 화장이 가능<br/>
일상생활에 지장이 없음
</p>
</li>
</ul>
</div>
</section>
</div>
</main>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
</th:block>
</html>

View File

@@ -0,0 +1,119 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/skin/skinTextureSelect.css?v1.0">
</th:block>
<th:block layout:fragment="layoutContent">
<div class="same">
<aside>
<ul>
<li class="first"><a href="#fraxel">프락셀 레이저</a></li>
<li><a href="#">IPL 레이저</a></li>
<li><a href="#">제네시스 레이저</a></li>
<li><a href="#">Co2 레이저</a></li>
</ul>
</aside>
<main>
<div id="fraxel">
<section class="main_img">
<img class="pc" src="/image/web/skin_main3.jpg" alt="diet"/>
<img class="mb" src="/image/web/Mskin_main3.jpg" alt="diet"/>
<div class="text_box">
<div class="left_text_box">
<p class="sub_title">피부 진피에 열과 물리적 자극을</p>
<p class="title">프락셀제나</p>
<p class="sub_text">
미세한 레이저 빔을 이용하여 피부 깊은 곳까지 <br/>
모공보다 미세한 구멍을 통과한 레이저는 <br/>
피부 진피에 열과 물리적 자극을 줍니다.
</p>
</div>
</div>
</section>
<section class="content1">
<div class="inner_wrap">
<p class="title">프락셀제나</p>
<p class="sub_title">프락셀의 업그레이드 버전으로 미국 FDA 승인을 받은 여드름흉터의 가장 기본이 되는 레이저입니다.</p>
<p class="sub_text">
모공축소나 흉터 치료의 경우 레이저 or 미세침으로 균일하고 미세하게 자극을 주어 피부 재생을 유도하는 형식으로 치료하게 됩니다.
메이드유에서는 다양한 형태의 흉터와 부위별 모공을 가장 적절한 치료로 진행할수 있도록 안내해 드리고 있습니다.
</p>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<h3><span>시술효과 </span>Effect</h3>
<ul>
<li><p>모공축소 및 <br/>피부재생</p></li>
<li><p>여드름 및 <br/>위축성 <br/>흉터</p></li>
<li><p>잔주름 및 <br/>탄력개선</p></li>
</ul>
</div>
</section>
<section class="content3">
<div class="inner_wrap">
<h3><span>특징 </span>Unique</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>적은 통증 - </span>미세 빔 방식의 레이저로 시술 중 통증 적음</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>빠른 회복 - </span>시술 후 적극적인 진정관리로 홍조, 딱지 최소화</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>다양한 치료 - </span>빔사이즈의 자유로운 조절로 다양한 흉터 치료</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>복합 치료 - </span>도트, 박리술 등 흉터치료법을 병용하여 효과적</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>새로운 콜라겐과 엘라스틴 생성으로 피부 노화를 개선</span></p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p><span>피부표면에서 피부 결과 피부톤을 개선</span></p>
</li>
</ul>
</div>
</section>
<section class="content4">
<div class="inner_wrap">
<h3><span>시술횟수 </span>Time</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/time.png" alt="check"/></div>
<p>4~6주 간격으로 5~10회 시술</p>
</li>
</ul>
</div>
</section>
<section class="content5">
<div class="inner_wrap">
<h3><span>주의사항 </span>Notice</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/notice.png" alt="check"/></div>
<p>
시술 강도, 피부상태에 따라 시술 직후 일시적 홍반 발생<br/>
시술 후 자가세안이나 화장이 가능<br/>
일상생활에 지장이 없음
</p>
</li>
</ul>
</div>
</section>
</div>
</main>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
</th:block>
</html>

View File

@@ -0,0 +1,116 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/skin/skinWaxingSelect.css?v1.0">
</th:block>
<th:block layout:fragment="layoutContent">
<div class="same">
<aside>
<ul>
<li class="first"><a href="#apogee">아포지플러스</a></li>
</ul>
</aside>
<main>
<div id="apogee">
<section class="main_img">
<img class="pc" src="/image/web/skin_main4.jpg" alt="diet"/>
<img class="mb" src="/image/web/Mskin_main4.jpg" alt="diet"/>
<div class="text_box">
<div class="left_text_box">
<p class="sub_title">프리미엄 제모 레이저 <span>아포지엘리트+</span></p>
<p class="title">APOGEE ELITE PLUS</p>
<p class="sub_text">
더욱 강해지 에너지 출력과 최대 2.5배 이상 시술 속도가 빠르고 <br/>
깊은 피부층까지 효율적인 에너지 전달이 가능한 안전한 레이저
</p>
</div>
</div>
</section>
<section class="content1">
<div class="inner_wrap">
<p class="title">아포지플러스제모</p>
<p class="sub_title">효과가 입증된 다양한 프리미엄 제모 전문레이저를 <br class="mb"/>이용한 개인별 부위별 1:1 맞춤제모시술</p>
<p class="sub_text">
효과가 입증된 다양한 프리미엄 제모 전문레이저를 이용한 개인별 부위별 1:1 맞춤제모시술. 제모 전문기기로 확실한 제모 효과를 얻을수 있습니다.
제모 시술 시 의사전담의가 직접 시술합니다. 메이드유는 프리미엄 전문 제모장비를 다량 보유하고 있습니다.
</p>
</div>
</section>
<section class="content2">
<div class="inner_wrap">
<h3><span>시술효과 </span>Effect</h3>
<ul>
<li><p>털의 <br/>굵기에 따라 <br/>맞춤 제모</p></li>
<li><p>흡수가 높은 <br/>레이저 파장으로 <br/>제모 효과</p></li>
<li><p>정상 피부 손상없이 <br/>선택적 모근 <br/>제모 효과</p></li>
</ul>
</div>
</section>
<section class="content3">
<div class="inner_wrap">
<h3><span>특징 </span>Unique</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>강력한 쿨링효과로 시술 시 통증이 거의 없음</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>두꺼운털부터 색이 옅은 털까지 확실하게 제모 가능</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>시술 속도가 빠르고 부작용이 거의 없는 안전한 시술</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>시술 후 모공 수축으로 피부가 부드러움</p>
</li>
<li>
<div><img src="/image/web/check.svg" alt="check"/></div>
<p>미국FDA승인 / 강력한 프리미엄 명품 제모레이저</p>
</li>
</ul>
</div>
</section>
<section class="content4">
<div class="inner_wrap">
<h3><span>시술횟수 </span>Time</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/time.png" alt="check"/></div>
<p>4~6주 간격으로 5~10회 시술</p>
</li>
</ul>
</div>
</section>
<section class="content5">
<div class="inner_wrap">
<h3><span>주의사항 </span>Notice</h3>
<ul class="box_list">
<li>
<div><img src="/image/web/notice.png" alt="check"/></div>
<p>
시술전, 털을 뽑지 마세요. 모공속에 털이 없으므로 레이저 제모 효과가 거의 없습니다.<br/>
제모 시술을 받기 2~3일 전에 면도를 하고 오시는 것이 좋습니다.<br/>
검은피부, 색소침착 피부에는 미백 연고를 처방하게 됩니다.<br/>
피부염증이나 질병이 있을 경우, 시술 전 먼저 치료합니다.<br/>
약물 복용이나 켈로이드 체질이 있으면 시술전에 말씀해 주셔야 합니다.<br/>
시술후에는 뽑거나, 왁싱을 금하며, 면도는 무방합니다.<br/>
건조함 방지를 위해 보습제를 발라주는 것이 좋습니다.<br/>
하루 이틀 정도 피부가 울긋불긋해지거나 조금 부을수 있으나 곧 사라집니다.
</p>
</li>
</ul>
</div>
</section>
</div>
</main>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
</th:block>
</html>

View File

@@ -0,0 +1,87 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<link rel="stylesheet" href="/css/web/voc/webVOC.css?ver=2">
</th:block>
<th:block layout:fragment="layoutContent">
<main>
<div class="inner_wrap">
<h3>
<span>칭찬/불만 접수</span>
</h3>
<hr class="hrtag"/>
<form name="dataform" id="dataform">
<table class="table table-bordered board_write">
<caption>글쓰기</caption>
<colgroup>
<col width="20%">
<col width="30%">
</colgroup>
<tbody>
<tr>
<th>지점선택</th>
<td >
<select name="gubun" class="form-select input_select">
<option value="GN">강남본점</option>
</select>
</td>
</tr>
<tr>
<th>고객명</th>
<td >
<input type="text" name="name" value="" placeholder='고객님의 성함을 입력해 주세요.' class="input_text">
</td>
</tr>
<tr>
<th class="board_txt1">휴대폰번호</th>
<td class="lm teltd" >
<div>
<input type="text" id="phoneNumber" name="phoneNumber" placeholder='고객님의 핸드폰 번호를 입력해 주세요.' class="input_tel">
<input type="button" class="input_button" name="sendAuthNumBtn" id="sendAuthNumBtn" Onclick="javascript:fn_sendAuthNum();" value="인증번호 발송">
</div>
<div class="bd-top">
<input type="text" class="input_auth" id="authNumber" name="authNumber" placeholder='인증번호를 입력해 주세요.'>
<p id="timer" class="input_time">03:00</p>
<input type="button" class="input_button noactive" name="sendAuthNumBtn" id="sendAuthNumBtn" Onclick="javascript:fn_selectPhoneAuthCheck();" value="인증번호 확인">
</div>
</td>
</tr>
<tr>
<th class="board_txt1">의견 분류</th>
<td class="lm" >
<input type='radio' class="input_radio" name='opinion' value='PR' id="a"/> <label class="label_radio" for='a'>칭찬</label>
<input type='radio' class="input_radio" name='opinion' value='DS' id="b"/> <label class="label_radio" for='b'>불만</label>
<input type='radio' class="input_radio" name='opinion' value='ET' id="c"/> <label class="label_radio" for='c'>기타의견</label>
</td>
</tr>
<tr>
<th class="board_txt1">내용입력</th>
<td class="lm" >
<textarea name="content" rows="15" class="input_text_area" id="Contents" placeholder='고객님의 소중한 의견을 입력해 주세요.'></textarea>
</td>
</tr>
</tbody>
</table>
<p>
<input type='checkbox' name="check" id="check" class="input_check"/> [필수] 서비스 이용 및 예약 신청을 위한 개인정보 제공에 동의
</p>
<p>
<a href="/webaccept/acceptPrivacy.do">[자세히 보기]</a>
</p>
<p>
<input type="button" class="input_button" Onclick="javascript:fn_submit();" value="의견 접수하기">
</p>
</form>
</div>
</main>
</th:block>
<th:block layout:fragment="layoutContentScript">
<script src="/js/web/voc/webVOC.js?ver=2"></script>
</th:block>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,782 @@
<!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="~{/web/layout/layout}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<th:block layout:fragment="layoutCss">
<!-- Choices.js CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/choices.js/10.2.0/choices.min.css" />
<style>
* { box-sizing: border-box; }
body {
font-family: 'Noto Sans KR', sans-serif;
margin: 0;
background: #f7f7f9;
color: #222;
}
#service-header {
background: #fff;
border-bottom: 1px solid #ececec;
padding: 14px 0 14px 24px;
font-size: 0.98em;
color: #888;
}
.main-wrap {
max-width: 1280px;
margin: 0 auto;
background: #fff;
border-radius: 18px;
box-shadow: 0 2px 12px rgba(0,0,0,0.07);
margin-top: 32px;
padding: 0 0 32px 0;
}
.top-section {
display: flex;
flex-wrap: wrap;
gap: 32px;
padding: 32px 32px 0 32px;
align-items: flex-start;
}
.img-box {
border-radius: 18px;
align-items: center;
justify-content: center;
overflow: hidden;
}
.img-box img {
width: 100%;
object-fit: cover;
border-radius: 18px;
}
.info-box {
flex: 1 1 300px;
min-width: 240px;
}
.info-title {
font-size: 1.7em;
font-weight: 700;
margin-bottom: 6px;
color: #222;
}
.info-desc {
color: #444;
font-size: 1.1em;
margin-bottom: 18px;
}
.info-price {
font-size: 1.2em;
font-weight: 700;
color: #b23c3c;
margin-bottom: 18px;
}
.select-row {
margin-bottom: 18px;
}
.select-row label {
font-weight: 500;
margin-bottom: 8px;
display: block;
}
.total-row {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 1.1em;
margin-bottom: 18px;
}
.total-row .total-label {
color: #888;
}
.total-row .total-price {
font-weight: bold;
color: #b23c3c;
}
.reserve-btn {
width: 100%;
padding: 14px 0;
background: #b23c3c;
color: #fff;
border: none;
border-radius: 8px;
font-size: 1.1em;
font-weight: bold;
cursor: pointer;
transition: background 0.15s;
}
.reserve-btn:disabled {
background: #ddd;
color: #888;
cursor: not-allowed;
}
.desc-section {
margin-top: 36px;
padding: 0 32px;
}
.desc-title {
font-size: 1.25em;
font-weight: 700;
margin-bottom: 12px;
color: #222;
}
.desc-content {
color: #444;
font-size: 1.05em;
line-height: 1.7;
margin-bottom: 20px;
}
.hashtag-section {
margin-top: 30px;
padding: 20px 0;
border-top: 1px solid #eee;
}
.hashtag-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.hashtag-list {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.hashtag {
display: inline-block;
background-color: #f8f9fa;
color: #495057;
padding: 8px 15px;
border-radius: 20px;
font-size: 14px;
text-decoration: none;
border: 1px solid #dee2e6;
transition: all 0.3s ease;
}
.hashtag:hover {
background-color: #007bff;
color: white;
border-color: #007bff;
cursor: pointer;
}
#thumbnail-bottom-txt{
padding: 8px;
margin-top: 10px;
background-color: #fff;
}
/* Choices.js 커스터마이징 - 개선된 버전 */
.choices {
border: 1px solid #ddd !important;
border-radius: 6px !important;
font-size: 1em !important;
background: #fff !important;
min-width: 300px !important;
}
.choices__inner {
background: #fff !important;
padding: 8px 12px !important;
min-height: 40px !important;
color: #222 !important;
min-width: 280px !important;
width: 100% !important;
}
/* 플레이스홀더 텍스트 잘림 방지 - 핵심 수정 */
.choices__placeholder {
color: #888 !important;
opacity: 1 !important;
width: 100% !important;
min-width: 200px !important;
white-space: nowrap !important;
overflow: visible !important;
text-overflow: clip !important;
display: block !important;
}
.choices__input {
color: #222 !important;
background: transparent !important;
min-width: 200px !important;
width: 100% !important;
}
.choices__input::placeholder {
color: #888 !important;
opacity: 1 !important;
width: 100% !important;
min-width: 200px !important;
white-space: nowrap !important;
overflow: visible !important;
}
/* 다중 선택시 입력 필드 너비 확보 */
.choices[data-type*="select-multiple"] .choices__input {
min-width: 200px !important;
width: auto !important;
flex: 1 !important;
}
/* 선택된 항목들과 입력 필드 공간 분배 */
.choices__list--multiple {
/* display: flex !important; */
flex-wrap: wrap !important;
align-items: center !important;
}
.choices__list--multiple:empty + .choices__input {
min-width: 200px !important;
width: 100% !important;
flex: 1 !important;
}
/* 선택된 항목의 가격 표시 스타일 - 새로 추가 */
.selected-item-content {
display: flex !important;
flex-direction: column !important;
align-items: flex-start !important;
flex: 1 !important;
}
.selected-item-name {
font-weight: 500 !important;
margin-bottom: 2px !important;
}
.selected-item-price {
font-size: 0.85em !important;
}
.selected-price {
color: #b23c3c !important;
font-weight: bold !important;
}
.selected-price-discount {
color: #b23c3c !important;
font-weight: bold !important;
font-size: 0.9em !important;
}
.selected-price-original {
color: #aaa !important;
font-size: 0.85em !important;
text-decoration: line-through !important;
margin-left: 4px !important;
}
/* 선택된 항목들 스타일 수정 */
.choices__list--multiple .choices__item {
background-color: #f8f9fa !important;
border: 1px solid #dee2e6 !important;
border-radius: 16px !important;
padding: 8px 12px !important;
margin: 2px !important;
font-size: 0.9em !important;
color: #495057 !important;
flex-shrink: 0 !important;
display: flex !important;
align-items: center !important;
/* max-width: 300px !important; */
}
/* 빨간색으로 변경 */
.choices__button {
background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjYjIzYzNjIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==') !important;
background-size: 14px 14px !important;
background-position: center !important;
background-repeat: no-repeat !important;
border-left:0 !important;
margin:0 !important;
padding:0 !important;
width:14px !important;
}
/* 드롭다운 컨테이너 */
.choices__list--dropdown {
background: #fff !important;
border: 1px solid #ddd !important;
border-radius: 6px !important;
box-shadow: 0 2px 8px rgba(0,0,0,0.1) !important;
}
/* 드롭다운 옵션들 스타일 */
.choices__list--dropdown .choices__item {
padding: 8px 12px !important;
display: flex !important;
justify-content: space-between !important;
align-items: center !important;
color: #222 !important;
}
.choices__list--dropdown .choices__item--selectable:hover {
background-color: #f5f5f5 !important;
color: #222 !important;
}
.choices__list--dropdown .choices__item--highlighted {
background-color: #b23c3c !important;
color: #fff !important;
}
/* 포커스 상태 */
.choices.is-focused .choices__inner {
border-color: #b23c3c !important;
}
/* 가격 표시 스타일 */
.procedure-price {
color: #b23c3c !important;
font-weight: bold !important;
font-size: 0.9em !important;
}
.procedure-price-discount {
color: #b23c3c !important;
font-weight: bold !important;
font-size: 0.9em !important;
}
.procedure-price-original {
color: #aaa !important;
font-size: 0.85em !important;
text-decoration: line-through !important;
margin-left: 4px !important;
}
/* 드롭다운이 열렸을 때 하이라이트된 항목의 가격 색상 */
.choices__list--dropdown .choices__item--highlighted .procedure-price,
.choices__list--dropdown .choices__item--highlighted .procedure-price-discount {
color: #fff !important;
}
.choices__list--dropdown .choices__item--highlighted .procedure-price-original {
color: #ddd !important;
}
/* 검색 입력창 스타일 */
.choices[data-type*="select-multiple"] .choices__input {
background-color: transparent !important;
color: #222 !important;
}
/* 비활성화 상태 */
.choices.is-disabled .choices__inner {
background-color: #f8f9fa !important;
color: #6c757d !important;
cursor: not-allowed !important;
}
/* 반응형 대응 */
@media (max-width: 600px) {
.choices {
min-width: 250px !important;
}
.choices__inner {
min-width: 230px !important;
}
.choices__placeholder,
.choices__input,
.choices__input::placeholder {
min-width: 150px !important;
}
.choices__list--multiple .choices__item {
max-width: 250px !important;
padding: 6px 10px !important;
}
.selected-item-name {
font-size: 0.9em !important;
}
.selected-item-price {
font-size: 0.8em !important;
}
.choices__list--multiple .choices__item[data-deletable] .choices__button {
width: 20px !important;
height: 20px !important;
font-size: 16px !important;
text-indent: 0 !important;
}
}
@media (max-width: 900px) {
.main-wrap { margin-top: 16px; }
.top-section { flex-direction: column; gap: 18px; padding: 20px 10px 0 10px; }
.img-box { width: 100%;}
.info-box { min-width: unset; }
.desc-section { padding: 0 10px; }
}
@media (max-width: 600px) {
.main-wrap { margin-top: 0; border-radius: 0; box-shadow: none; }
.top-section { padding: 12px 2vw 0 2vw; }
.desc-section { padding: 0 2vw; }
}
</style>
</th:block>
<th:block layout:fragment="layout_top_script">
<script th:inline="javascript">
let category_div_cd = [[${CATEGORY_DIV_CD}]];
let category_no = [[${CATEGORY_NO}]];
let post_no = [[${POST_NO}]];
const CDN_URL = [[${@environment.getProperty('url.cdn')}]];
</script>
</th:block>
<th:block layout:fragment="layoutContent">
<div id="service-header">
시술안내/가격 &nbsp;&gt;&nbsp; <span id="header-category-nm"></span> &nbsp;&gt;&nbsp; <span id="header-title"></span>
</div>
<div class="main-wrap">
<div class="top-section">
<div class="img-box">
<img id="serviceThumb" th:src="${@environment.getProperty('madeu.logo.size800x450')}" alt="썸네일 이미지">
<pre id="thumbnail-bottom-txt"></pre>
</div>
<div class="info-box">
<div class="info-title" id="title">메쉬다 D/S</div>
<div class="info-desc" id="contents">전신 라인 정리에 특화된 메쉬다 바디주사!</div>
<div class="hashtag-section">
<div class="hashtag-container">
<div class="hashtag-list">
<span class="hashtag">#메쉬다바디주사</span>
<span class="hashtag">#쥬베룩</span>
<span class="hashtag">#바디라인정리</span>
<span class="hashtag">#콜라겐부스터</span>
<span class="hashtag">#전신시술</span>
<span class="hashtag">#자연스러운볼륨</span>
<span class="hashtag">#빠른회복</span>
<span class="hashtag">#합리적가격</span>
</div>
</div>
</div>
<div class="info-price"><span id="price">0</span>원 부터</div>
<div class="select-row">
<label for="procedure-select">시술 선택</label>
<select id="procedure-select" multiple></select>
</div>
<div class="total-row">
<span class="total-label">총 금액</span>
<span class="total-price" id="total">0원</span>
</div>
<button class="reserve-btn" id="reserve-btn" disabled>시술 예약하기</button>
</div>
</div>
<div class="desc-section">
<!-- <div class="desc-content">
<img id="contents_path" th:src="${@environment.getProperty('madeu.logo.size800x450')}" alt="컨텐츠 이미지" width="100%" />
</div> -->
</div>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
<!-- Choices.js JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/choices.js/10.2.0/choices.min.js"></script>
<script>
// 전역 변수
let procedureChoices;
let priceList = [];
const totalEl = document.getElementById('total');
const reserveBtn = document.getElementById('reserve-btn');
// 초기화
fn_SelectDetail(category_div_cd, category_no, post_no);
/****************************************************************************
* 카테고리 목록 가져오기
****************************************************************************/
function fn_SelectDetail(category_div_cd, category_no, post_no) {
let formData = new FormData();
formData.append('CATEGORY_DIV_CD', category_div_cd);
formData.append('CATEGORY_NO', category_no);
formData.append('POST_NO', post_no);
$.ajax({
url: encodeURI('/webevent/selectEventDetail.do'),
data: formData,
dataType: 'json',
processData: false,
contentType: false,
type: 'POST',
async: true,
success: function(data) {
if(data.msgCode == '0') {
// 화면 데이터 변경
$('#title').text(data.rows.TITLE);
$('#serviceThumb').attr('src', CDN_URL + data.rows.THUMBNAIL_PATH);
$('#thumbnail-bottom-txt').text(data.rows.THUMBNAIL_BOTTOM_TXT);
$('#contents').text(data.rows.CONTENT);
if(data.rows.PRICE == null || data.rows.PRICE == undefined) {
$('#price').text('0');
} else {
$('#price').text(data.rows.PRICE.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
}
// header 동적 변경
$('#header-category-nm').text(data.rows.CATEGORY_NM);
$('#header-title').text(data.rows.TITLE);
// 해시태그 처리
var hashtagHtml = '';
if (data.rows.HASHTAG) {
var tags = data.rows.HASHTAG.split('#');
tags.forEach(function(tag) {
var trimmed = tag.trim();
if(trimmed) {
hashtagHtml += '<span class="hashtag">#' + trimmed + '</span>';
}
});
}
$('.hashtag-list').html(hashtagHtml);
$('#contents_path').attr('src', CDN_URL + data.rows.CONTENTS_PATH);
// 시술 목록 데이터 처리
updateProcedureOptions(data.price || []);
} else {
modalEvent.danger("조회 오류", data.msgDesc);
}
},
error: function(xhr, status, error) {
modalEvent.danger("조회 오류", "조회 중 오류가 발생하였습니다. 잠시후 다시시도하십시오.");
},
beforeSend: function() {
$(".loading-image-layer").show();
},
complete: function() {
$(".loading-image-layer").hide();
}
});
}
/****************************************************************************
* Choices.js 초기화 및 옵션 업데이트
****************************************************************************/
function updateProcedureOptions(data) {
priceList = data;
// 기존 Choices 인스턴스 제거
if (procedureChoices) {
procedureChoices.destroy();
}
// 선택 옵션 데이터 생성
const choices = data.map(item => {
if (!item.MU_TREATMENT_PROCEDURE_ID || !item.TREATMENT_PROCEDURE_NAME) return null;
const basePrice = (item.PRICE || 0) + (item.VAT || 0);
const discountPrice = item.DISCOUNT_PRICE;
return {
value: item.MU_TREATMENT_PROCEDURE_ID,
label: item.TREATMENT_PROCEDURE_NAME,
customProperties: {
name: item.TREATMENT_PROCEDURE_NAME,
price: basePrice,
discountPrice: discountPrice,
originalData: item
}
};
}).filter(Boolean);
// Choices.js 초기화
procedureChoices = new Choices('#procedure-select', {
removeItemButton: true,
searchEnabled: true,
searchPlaceholderValue: '시술명으로 검색...',
placeholder: true,
placeholderValue: '시술을 선택하세요',
maxItemCount: -1,
choices: choices,
shouldSort: false,
searchResultLimit: 10,
searchFields: ['label', 'value'],
itemSelectText: '',
noChoicesText: '선택 가능한 시술이 없습니다',
noResultsText: '검색 결과가 없습니다',
loadingText: '시술 정보를 불러오는 중...',
// 템플릿 커스터마이징 - 선택된 항목에 가격 표시 추가
callbackOnCreateTemplates: function(template) {
return {
// 선택된 항목 템플릿 - 가격 정보 포함
item: ({ classNames }, data) => {
const customProps = data.customProperties || {};
const name = customProps.name || data.label;
const price = customProps.price || 0;
const discountPrice = customProps.discountPrice;
// 가격 표시 HTML 생성
let priceHtml = '';
if (discountPrice && discountPrice < price) {
priceHtml = `
<span class="selected-price-discount">${discountPrice.toLocaleString()}원</span>
<span class="selected-price-original">${price.toLocaleString()}원</span>
`;
} else {
priceHtml = `<span class="selected-price">${price.toLocaleString()}원</span>`;
}
return template(`
<div class="${classNames.item} ${data.highlighted ? classNames.highlightedState : classNames.itemSelectable}" data-item data-id="${data.id}" data-value="${data.value}">
<span class="selected-item-content">
<span class="selected-item-name">${name}</span>
<span class="selected-item-price">${priceHtml}</span>
</span>
<button type="button" class="${classNames.button}" aria-label="Remove item: '${data.value}'" data-button>X</button>
</div>
`);
},
// 드롭다운 선택 옵션 템플릿
choice: ({ classNames }, data) => {
const customProps = data.customProperties || {};
const name = customProps.name || data.label;
const price = customProps.price || 0;
const discountPrice = customProps.discountPrice;
let priceHtml = '';
if (discountPrice && discountPrice < price) {
priceHtml = `
<span class="procedure-price-discount">${discountPrice.toLocaleString()}원</span>
<span class="procedure-price-original">${price.toLocaleString()}원</span>
`;
} else {
priceHtml = `<span class="procedure-price">${price.toLocaleString()}원</span>`;
}
return template(`
<div class="${classNames.item} ${classNames.itemChoice} ${data.disabled ? classNames.itemDisabled : classNames.itemSelectable}" data-select-text="" data-choice ${data.disabled ? 'data-choice-disabled aria-disabled="true"' : 'data-choice-selectable'} data-id="${data.id}" data-value="${data.value}">
<div style="display: flex; justify-content: space-between; width: 100%; align-items: center;">
<span>${name}</span>
${priceHtml}
</div>
</div>
`);
}
};
}
});
// 이벤트 리스너 추가
const selectElement = document.getElementById('procedure-select');
selectElement.addEventListener('change', function(event) {
console.log('Selection changed:', event.detail);
updateTotalPrice();
});
selectElement.addEventListener('addItem', function(event) {
console.log('Item added:', event.detail);
updateTotalPrice();
});
selectElement.addEventListener('removeItem', function(event) {
console.log('Item removed:', event.detail);
updateTotalPrice();
});
}
/****************************************************************************
* 총 금액 업데이트 - 개선된 버전
****************************************************************************/
function updateTotalPrice() {
if (!procedureChoices) {
console.log('procedureChoices not initialized');
return;
}
const selectedValues = procedureChoices.getValue(true);
console.log('Selected values:', selectedValues);
let total = 0;
selectedValues.forEach(value => {
const item = priceList.find(p => p.MU_TREATMENT_PROCEDURE_ID == value);
console.log('Found item for value', value, ':', item);
if (item) {
const basePrice = (item.PRICE || 0) + (item.VAT || 0);
const discountPrice = item.DISCOUNT_PRICE;
// 할인가가 있고 더 저렴하면 할인가 사용, 아니면 기본가격 사용
const finalPrice = (discountPrice && discountPrice < basePrice) ? discountPrice : basePrice;
total += finalPrice;
console.log('Added price:', finalPrice);
}
});
console.log('Total calculated:', total);
totalEl.textContent = total.toLocaleString() + '원';
reserveBtn.disabled = selectedValues.length === 0;
}
/****************************************************************************
* 예약 페이지로 이동
****************************************************************************/
function fn_moveReservation(category_div, category_no, post_no) {
if (!procedureChoices) {
alert('시술 선택 기능이 초기화되지 않았습니다.');
return;
}
const selectedValues = procedureChoices.getValue(true);
if (selectedValues.length === 0) {
alert('시술을 선택해주세요.');
return;
}
const form = document.createElement('form');
form.method = 'post';
form.action = '/webevent/selectMakeReservation.do';
// 기본 파라미터 추가
const params = [
{ name: 'CATEGORY_DIV_CD', value: category_div },
{ name: 'CATEGORY_NO', value: category_no },
{ name: 'POST_NO', value: post_no }
];
params.forEach(param => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = param.name;
input.value = param.value;
form.appendChild(input);
});
// 선택된 시술 추가
selectedValues.forEach(value => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'PROCEDURE_ID';
input.value = value;
form.appendChild(input);
});
document.body.appendChild(form);
form.submit();
}
// 예약 버튼 이벤트
reserveBtn.addEventListener('click', function() {
fn_moveReservation(category_div_cd, category_no, post_no);
});
</script>
</th:block>
</html>

View File

@@ -0,0 +1,594 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<style>
* {
box-sizing: border-box;
}
/* 전체 기본 스타일 */
html, body {
height: 100vh;
margin: 0;
padding: 0;
font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
background: #f8f9fa;
color: #1a1a1a;
overflow-x: hidden;
font-size: 16px;
line-height: 1.6;
}
/* 메인 컨테이너 */
.container {
max-width: 1280px;
width: 100%;
margin: 0 auto;
min-height: calc(100vh - 300px);
display: flex;
flex-direction: column;
gap: 1.5rem;
}
/* 상단 헤더 영역 */
.header {
background: white;
border-radius: 16px;
box-shadow: 0 2px 16px rgba(0,0,0,0.06);
padding: 1rem 2rem;
border-bottom: 3px solid #C60B24;
flex-shrink: 0;
}
.page-title {
font-size: clamp(1.5rem, 3vw, 1.875rem); /* 24px ~ 30px */
font-weight: 700;
color: #1a1a1a;
margin: 0;
letter-spacing: -0.025em;
}
/* 하단 콘텐츠 영역 (사이드바 + 메인) */
.content-wrapper {
flex: 1;
display: flex;
gap: 1.5rem;
min-height: 0;
}
/* 좌측 사이드바 */
.sidebar {
width: 240px;
min-width: 220px;
flex-shrink: 0;
background: white;
border-radius: 16px;
box-shadow: 0 2px 16px rgba(0,0,0,0.06);
height: fit-content;
max-height: 100%;
overflow-y: auto;
position: sticky;
top: 0;
}
.sidebar-header {
padding: 1.25rem 1.5rem;
font-size: 1.125rem; /* 18px */
font-weight: 700;
color: #C60B24;
border-bottom: 1px solid #e9ecef;
}
.category-list {
list-style: none;
padding: 1rem;
margin: 0;
}
.category-item {
margin-bottom: 0.375rem;
}
.category-link {
display: block;
width: 100%;
padding: 0.75rem 1rem;
font-size: 0.95rem; /* 15.2px */
color: #6b7280;
text-decoration: none;
background: none;
border: none;
border-radius: 10px;
cursor: pointer;
transition: all 0.2s ease;
text-align: left;
}
.category-link:hover {
background: #f9fafb;
color: #C60B24;
transform: translateX(2px);
}
.category-link.active {
background: rgba(198, 11, 36, 0.08);
color: #C60B24;
font-weight: 600;
border-left: 4px solid #C60B24;
}
/* 메인 콘텐츠 영역 */
.main-content {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
}
/* 이벤트 리스트 */
.event-list {
flex: 1;
overflow-y: auto;
padding-right: 0.5rem;
min-height: 0;
}
.event-grid {
display: flex;
flex-direction: column;
gap: 1.25rem;
padding-bottom: 2rem;
}
/* 이벤트 카드 */
.event-card {
display: flex;
background: white;
border-radius: 16px;
box-shadow: 0 2px 16px rgba(0,0,0,0.06);
overflow: hidden;
transition: all 0.3s ease;
border: 1px solid #f1f5f9;
min-height: 160px;
cursor: pointer;
}
.event-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 32px rgba(0,0,0,0.12);
border-color: #C60B24;
}
.event-img {
width: 340px;
min-width: 280px;
background: #f3f4f6;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.event-img img {
width: 100%;
object-fit: cover;
display: block;
}
.event-info {
flex: 1;
padding: 1.5rem;
display: flex;
flex-direction: column;
justify-content: space-between;
position: relative;
}
.event-title {
font-size: 1.25rem; /* 20px */
font-weight: 700;
margin-bottom: 0.5rem;
color: #1a1a1a;
letter-spacing: -0.025em;
}
.event-desc {
color: #6b7280;
font-size: 0.9375rem; /* 15px */
margin-bottom: 0.75rem;
line-height: 1.5;
}
.event-meta {
font-size: 0.875rem; /* 14px */
color: #9ca3af;
margin-bottom: 1rem;
}
.event-price {
font-size: 1.125rem; /* 18px */
color: #C60B24;
font-weight: 700;
margin-bottom: 0;
}
/* 로딩 및 에러 메시지 */
.loading {
text-align: center;
padding: 2rem;
color: #6b7280;
font-size: 0.9375rem; /* 15px */
}
.error-message {
text-align: center;
padding: 2rem;
color: #dc2626;
font-size: 0.9375rem; /* 15px */
}
/* 스크롤바 커스터마이징 */
.event-list::-webkit-scrollbar,
.sidebar::-webkit-scrollbar {
width: 6px;
}
.event-list::-webkit-scrollbar-track,
.sidebar::-webkit-scrollbar-track {
background: #f8fafc;
border-radius: 3px;
}
.event-list::-webkit-scrollbar-thumb,
.sidebar::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 3px;
}
.event-list::-webkit-scrollbar-thumb:hover,
.sidebar::-webkit-scrollbar-thumb:hover {
background: #C60B24;
}
/* 반응형 디자인 - 태블릿 */
@media (max-width: 1024px) {
.container {
padding: 1rem;
gap: 1rem;
}
.content-wrapper {
gap: 1rem;
}
.sidebar {
width: 220px;
min-width: 200px;
}
.event-img {
width: 220px;
min-width: 220px;
}
.event-img img {
height: 140px;
}
.header {
padding: 1.25rem 1.5rem;
}
.page-title {
font-size: clamp(1.375rem, 2.8vw, 1.75rem); /* 22px ~ 28px */
}
}
/* 반응형 디자인 - 모바일 */
@media (max-width: 768px) {
.container {
flex-direction: column;
padding: 1rem;
gap: 1rem;
}
.content-wrapper {
flex-direction: column;
gap: 1rem;
}
.sidebar {
width: 100%;
position: static;
max-height: none;
order: 1;
}
.category-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 0.5rem;
padding: 1rem;
}
.category-link {
text-align: center;
padding: 0.75rem 0.5rem;
font-size: 0.875rem; /* 14px */
}
.main-content {
order: 2;
}
.event-list {
overflow-y: visible;
height: auto;
}
.event-card {
flex-direction: column;
min-height: auto;
}
.event-img {
width: 100%;
min-width: auto;
}
.event-img img {
height: 200px;
}
.event-info {
padding: 1.25rem;
}
.header {
padding: 1rem 1.5rem;
border-radius: 12px;
}
.page-title {
font-size: clamp(1.25rem, 2.5vw, 1.5rem); /* 20px ~ 24px */
}
.event-title {
font-size: 1.125rem; /* 18px */
}
.event-price {
font-size: 1rem; /* 16px */
}
}
/* 작은 모바일 */
@media (max-width: 480px) {
.container {
padding: 0.75rem;
}
.header {
padding: 0.875rem 1rem;
}
.page-title {
font-size: clamp(1.125rem, 2.2vw, 1.375rem); /* 18px ~ 22px */
}
.event-info {
padding: 1rem;
}
.event-title {
font-size: 1rem; /* 16px */
}
.event-desc {
font-size: 0.875rem; /* 14px */
}
}
</style>
</th:block>
<th:block layout:fragment="layout_top_script">
<script th:inline="javascript">
const CDN_URL = [[${@environment.getProperty('url.cdn')}]];
</script>
</th:block>
<th:block layout:fragment="layoutContent">
<div class="container">
<!-- 상단 헤더 영역 -->
<div class="header">
<h1 class="page-title">이벤트 안내</h1>
</div>
<!-- 하단 콘텐츠 영역 (사이드바 + 메인) -->
<div class="content-wrapper">
<!-- 좌측 사이드바 -->
<aside class="sidebar">
<div class="sidebar-header">이달의 이벤트</div>
<ul class="category-list" id="category-list">
<!-- 카테고리 JS로 렌더링 -->
</ul>
</aside>
<!-- 메인 콘텐츠 -->
<main class="main-content">
<div class="event-list">
<div class="event-grid" id="event-grid">
<!-- 이벤트 카드 JS로 렌더링 -->
</div>
</div>
</main>
</div>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
<script>
class EventManager {
constructor() {
this.events = [];
this.categories = [];
this.init();
}
async init() {
await this.loadCategories();
}
async apiRequest(url, data) {
return new Promise((resolve, reject) => {
$.ajax({
url: encodeURI(url),
data: data,
dataType: 'json',
processData: false,
contentType: false,
type: 'POST',
success: resolve,
error: reject,
beforeSend: () => $(".loading-image-layer").show(),
complete: () => $(".loading-image-layer").hide()
});
});
}
async loadCategories() {
try {
const formData = new FormData();
formData.append('bannerType', 'A');
const data = await this.apiRequest('/webevent/selectListWebEvent.do', formData);
if (data.msgCode === '0') {
this.categories = data.rows;
this.renderCategories();
if (this.categories.length > 0) {
this.loadEvents(this.categories[0].CATEGORY_NO);
}
} else {
modalEvent.danger("조회 오류", data.msgDesc);
}
} catch (error) {
modalEvent.danger("조회 오류", "조회 중 오류가 발생하였습니다.");
}
}
async loadEvents(categoryNo) {
try {
const formData = new FormData();
formData.append('category_no', categoryNo);
const data = await this.apiRequest('/webevent/selectListEvent.do', formData);
if (data.msgCode === '0') {
this.events = data.rows.map(row => ({
img: CDN_URL + row.THUMBNAIL_PATH,
title: row.TITLE,
desc: row.CONTENT,
meta: row.THUMBNAIL_BOTTOM_TXT,
price: {
before: Number(row.PRICE) || 0,
after: Number(row.DISCOUNT_PRICE) || 0
},
categoryDiv: row.CATEGORY_DIV_CD,
categoryNo: row.CATEGORY_NO,
postNo: row.POST_NO
}));
this.renderEvents();
} else {
modalEvent.danger("조회 오류", data.msgDesc);
}
} catch (error) {
modalEvent.danger("조회 오류", "조회 중 오류가 발생하였습니다.");
}
}
renderCategories() {
const html = this.categories.map((cat, idx) => `
<li class="category-item">
<a href="#" class="category-link ${idx === 0 ? 'active' : ''}"
data-category="${cat.CATEGORY_NO}">${cat.CATEGORY_NM}</a>
</li>
`).join('');
document.getElementById('category-list').innerHTML = html;
document.querySelectorAll('.category-link').forEach(link => {
link.addEventListener('click', (e) => {
e.preventDefault();
document.querySelectorAll('.category-link').forEach(item =>
item.classList.remove('active'));
link.classList.add('active');
this.loadEvents(link.dataset.category);
document.querySelector('.event-list').scrollTop = 0;
});
});
}
renderEvents() {
const html = this.events.map(event => `
<div class="event-card" data-category-div="${event.categoryDiv}"
data-category-no="${event.categoryNo}" data-post-no="${event.postNo}">
<div class="event-img">
<img src="${event.img}" alt="${event.title}">
</div>
<div class="event-info">
<div class="event-title">${event.title}</div>
<div class="event-desc">${event.desc}</div>
${event.meta ? `<div class="event-meta">${event.meta}</div>` : ''}
<div class="event-price">
<span style="text-decoration:line-through; color:#9ca3af; font-size:0.95em; margin-right:8px;">
${event.price.before.toLocaleString()}
</span>
${event.price.after.toLocaleString()}원 부터
</div>
</div>
</div>
`).join('');
document.getElementById('event-grid').innerHTML = html;
// 카드 클릭 이벤트 추가
document.querySelectorAll('.event-card').forEach(card => {
card.addEventListener('click', () => {
const categoryDiv = card.dataset.categoryDiv;
const categoryNo = card.dataset.categoryNo;
const postNo = card.dataset.postNo;
this.goToDetail(categoryDiv, categoryNo, postNo);
});
});
}
goToDetail(categoryDiv, categoryNo, postNo) {
const form = document.createElement('form');
form.method = 'post';
form.action = '/webevent/selectEventDetailIntro.do';
const fields = [
{ name: 'CATEGORY_DIV_CD', value: categoryDiv },
{ name: 'CATEGORY_NO', value: categoryNo },
{ name: 'POST_NO', value: postNo }
];
fields.forEach(field => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = field.name;
input.value = field.value;
form.appendChild(input);
});
document.body.appendChild(form);
form.submit();
}
}
const eventManager = new EventManager();
</script>
</th:block>
</html>

View File

@@ -0,0 +1,579 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<style>
:root {
--main-bg: #f6f7fb;
--card-bg: #fff;
--accent: #b23c3c;
--text: #222;
--muted: #888;
--shadow: 0 2px 12px rgba(0,0,0,0.07);
--radius: 18px;
}
.project_wrap section:not(.main_img) {
padding-top: 0px;
}
* { box-sizing: border-box; }
body {
margin: 0;
font-family: 'Noto Sans KR', sans-serif;
background: var(--main-bg);
color: var(--text);
min-height: 100vh;
}
/* 부트스트랩 컨테이너 모든 클래스 강제 덮어쓰기 */
.container,
.container-fluid,
.container-sm,
.container-md,
.container-lg,
.container-xl,
.container-xxl,
div[class*="container"] {
max-width: 1280px !important;
width: 100% !important;
margin-left: auto !important;
margin-right: auto !important;
padding-left: 0 !important;
padding-right: 0 !important;
box-sizing: border-box !important;
}
.detail-card {
background: var(--card-bg);
border-radius: var(--radius);
box-shadow: var(--shadow);
margin: 40px 0;
display: flex;
gap: 40px;
padding: 40px;
align-items: flex-start;
flex-wrap: wrap;
transition: box-shadow 0.17s;
}
.detail-card:hover {
box-shadow: 0 6px 24px rgba(178,60,60,0.14);
}
.photo-section {
flex: 0 0 650px;
width: 650px;
display: flex;
flex-direction: column;
align-items: center;
gap: 22px;
}
.compare-slider {
position: relative;
width: 650px;
height: 650px;
border-radius: 14px;
overflow: hidden;
box-shadow: 0 1px 8px rgba(0,0,0,0.06);
background: #f1f1f4;
margin-bottom: 6px;
user-select: none;
touch-action: none;
}
.compare-slider img {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
object-fit: cover;
transition: filter 0.2s;
}
.compare-slider .after-img {
clip-path: inset(0 0 0 50%);
z-index: 2;
transition: clip-path 0.2s;
}
.compare-slider .before-img {
z-index: 1;
}
.compare-slider .slider-bar {
position: absolute;
top: 0; left: 50%;
width: 3px; height: 100%;
background: var(--accent);
z-index: 3;
cursor: ew-resize;
transition: background 0.2s;
border-radius: 2px;
box-shadow: 0 0 4px rgba(178,60,60,0.15);
}
.compare-slider .slider-dot {
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
width: 28px; height: 28px;
background: var(--accent);
border-radius: 50%;
border: 3px solid #fff;
box-shadow: 0 2px 10px rgba(178,60,60,0.10);
z-index: 4;
cursor: ew-resize;
display: flex; align-items: center; justify-content: center;
color: #fff; font-size: 1.2em;
}
/* 트렌디한 Before/After 라벨 스타일 */
.compare-labels {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
margin-top: 12px;
position: relative;
z-index: 5;
}
.compare-labels span {
font-size: 1.1em; /* 크기 확대 */
font-weight: 700;
padding: 8px 24px; /* 패딩 증가 */
border-radius: 25px; /* 더 둥글게 */
letter-spacing: 0.5px;
position: relative;
transition: all 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);
cursor: pointer;
text-transform: uppercase;
backdrop-filter: blur(10px);
border: 2px solid transparent;
overflow: hidden;
}
/* Before 라벨 기본 상태 */
.compare-labels .before-label {
background: linear-gradient(135deg, rgba(255, 59, 92, 0.9), rgba(255, 94, 121, 0.8));
color: #fff;
box-shadow:
0 4px 15px rgba(255, 59, 92, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
/* After 라벨 기본 상태 */
.compare-labels .after-label {
background: linear-gradient(135deg, rgba(46, 213, 115, 0.9), rgba(0, 184, 148, 0.8));
color: #fff;
box-shadow:
0 4px 15px rgba(46, 213, 115, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
/* Before 강조 상태 */
.compare-labels .before-label.active {
background: linear-gradient(135deg, #ff3b5c, #ff5e79);
transform: scale(1.15) translateY(-3px);
box-shadow:
0 8px 25px rgba(255, 59, 92, 0.6),
0 0 30px rgba(255, 59, 92, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.3);
border-color: rgba(255, 255, 255, 0.3);
text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
}
/* After 강조 상태 */
.compare-labels .after-label.active {
background: linear-gradient(135deg, #2ed573, #00b894);
transform: scale(1.15) translateY(-3px);
box-shadow:
0 8px 25px rgba(46, 213, 115, 0.6),
0 0 30px rgba(46, 213, 115, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.3);
border-color: rgba(255, 255, 255, 0.3);
text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
}
/* 글로우 효과를 위한 가상 요소 */
.compare-labels span::before {
content: '';
position: absolute;
top: -2px; left: -2px; right: -2px; bottom: -2px;
background: inherit;
border-radius: inherit;
z-index: -1;
filter: blur(8px);
opacity: 0;
transition: opacity 0.4s ease;
}
.compare-labels span.active::before {
opacity: 0.7;
}
/* 애니메이션 키프레임 */
@keyframes pulse {
0%, 100% {
transform: scale(1.15) translateY(-3px);
}
50% {
transform: scale(1.18) translateY(-4px);
}
}
.compare-labels span.active {
animation: pulse 2s ease-in-out infinite;
}
/* 호버 효과 (추가 상호작용) */
.compare-labels span:hover:not(.active) {
transform: scale(1.05) translateY(-1px);
filter: brightness(1.1);
}
.info-section {
flex: 1;
min-width: 400px;
display: flex;
flex-direction: column;
gap: 18px;
}
.detail-title {
font-size: 1.45em;
font-weight: 700;
color: var(--accent);
margin-bottom: 4px;
}
.detail-desc {
color: var(--text);
font-size: 1.05em;
line-height: 1.6;
margin-bottom: 6px;
}
.detail-meta {
color: var(--muted);
font-size: 0.98em;
margin-bottom: 10px;
}
.tag-list {
display: flex;
flex-wrap: wrap;
gap: 7px;
margin-bottom: 10px;
}
.tag {
background: #f5eaea;
color: var(--accent);
font-size: 0.97em;
border-radius: 10px;
padding: 4px 14px;
font-weight: 500;
}
.back-link {
display: inline-block;
margin-top: 18px;
color: var(--accent);
font-weight: 600;
text-decoration: none;
border-bottom: 1.5px solid #b23c3c33;
font-size: 1em;
transition: color 0.13s;
}
.back-link:hover { color: #a12f2f; }
/* 태블릿 크기 (1024px 이하) */
@media (max-width: 1024px) {
.container,
.container-fluid,
.container-sm,
.container-md,
.container-lg,
.container-xl,
.container-xxl,
div[class*="container"] {
max-width: 100% !important;
padding-left: 20px !important;
padding-right: 20px !important;
}
.photo-section {
flex: 0 0 500px;
width: 500px;
}
.compare-slider {
width: 500px;
height: 500px;
}
.info-section {
min-width: 300px;
}
}
/* 모바일 크기 (768px 이하) */
@media (max-width: 768px) {
.container,
.container-fluid,
.container-sm,
.container-md,
.container-lg,
.container-xl,
.container-xxl,
div[class*="container"] {
padding-left: 15px !important;
padding-right: 15px !important;
}
.detail-card {
flex-direction: column;
gap: 24px;
padding: 30px 20px;
margin: 20px 0;
}
.photo-section {
flex: none;
width: 100%;
align-items: center;
}
.compare-slider {
width: 100%;
height: 400px;
max-width: 400px;
}
.info-section {
min-width: auto;
}
/* 모바일 라벨 크기 조정 */
.compare-labels span {
font-size: 1em;
padding: 6px 18px;
}
.compare-labels span.active {
transform: scale(1.1) translateY(-2px);
}
@keyframes pulse {
0%, 100% {
transform: scale(1.1) translateY(-2px);
}
50% {
transform: scale(1.13) translateY(-3px);
}
}
}
/* 작은 모바일 (480px 이하) */
@media (max-width: 480px) {
.container,
.container-fluid,
.container-sm,
.container-md,
.container-lg,
.container-xl,
.container-xxl,
div[class*="container"] {
padding-left: 10px !important;
padding-right: 10px !important;
}
.detail-card {
border-radius: 10px;
padding: 20px 15px;
}
.compare-slider {
border-radius: 8px;
height: 350px;
}
.info-section {
padding: 0 5px;
}
.detail-title {
font-size: 1.3em;
}
.compare-labels span {
font-size: 0.9em;
padding: 5px 15px;
}
}
/* 매우 작은 화면 (360px 이하) */
@media (max-width: 360px) {
.compare-slider {
height: 300px;
}
.detail-card {
padding: 15px 10px;
}
}
</style>
</th:block>
<th:block layout:fragment="layout_top_script">
<script th:inline="javascript">
let category_div_cd = [[${CATEGORY_DIV_CD}]];
let category_no = [[${CATEGORY_NO}]];
let post_no = [[${POST_NO}]];
</script>
</th:block>
<th:block layout:fragment="layoutContent">
<div class="container">
<div class="detail-card">
<!-- 이미지 비교 영역 -->
<section class="photo-section">
<div class="compare-slider" id="compare-slider">
<img id="before" src="https://images.unsplash.com/photo-1518717758536-85ae29035b6d?auto=format&fit=facearea&w=600&h=400" alt="여드름 치료 전" class="before-img">
<img id="after" src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=facearea&w=600&h=400" alt="여드름 치료 후" class="after-img">
<div class="slider-bar"></div>
<div class="slider-dot">&#8596;</div>
</div>
<div class="compare-labels">
<span class="before-label">Before</span>
<span class="after-label">After</span>
</div>
</section>
<!-- 상세 정보 영역 -->
<section class="info-section">
<div class="detail-title" id="title">여드름 치료 4주차</div>
<div class="detail-meta" id="info">카테고리: 여드름 &nbsp;|&nbsp; 등록일: 2025-07-12</div>
<div class="tag-list">
<span class="tag">#여드름</span>
<span class="tag">#피부개선</span>
<span class="tag">#4주차</span>
</div>
<div class="detail-desc" id="contents">
붉은 여드름과 염증이 4주간의 치료 후 눈에 띄게 완화되었습니다.<br>
피부결이 매끄러워지고, 자극 없이 자연스럽게 개선된 사례입니다.
</div>
<div class="detail-desc" style="color:#b23c3c; font-weight:500;">
※ 시술 결과는 개인에 따라 다를 수 있습니다.
</div>
<a href="#" class="back-link" onclick="history.back();return false;">목록으로 돌아가기</a>
</section>
</div>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
<script>
//CDN_URL 전역 정의
const CDN_URL = "[(${@environment.getProperty('url.cdn')})]";
fn_SelectDetail(category_div_cd, category_no, post_no);
/****************************************************************************
* 카테고리 목록 가져오기
****************************************************************************/
function fn_SelectDetail(category_div_cd, category_no, post_no){
let formData = new FormData();
formData.append('CATEGORY_DIV_CD', category_div_cd);
formData.append('CATEGORY_NO', category_no);
formData.append('POST_NO', post_no);
$.ajax({
url: encodeURI('/webphoto/selectPhotoDetail.do'),
data: formData,
dataType: 'json',
processData: false,
contentType: false,
type: 'POST',
async: true,
success: function(data){
if(data.msgCode=='0'){
//화면 데이터 변경
$('#title').text(data.rows.TITLE);
$('#before').attr('src', CDN_URL + data.rows.BEFORE_PATH);
$('#after').attr('src', CDN_URL + data.rows.AFTER_PATH);
$('#contents').text(data.rows.CONTENT);
// 정보 동적 변경
$('#info').html('카테고리: ' + data.rows.CATEGORY_NM + ' &nbsp;|&nbsp; 등록일: ' + formatDate(data.rows.REG_DATE));
// 해시태그 처리
var hashtagHtml = '';
if (data.rows.HASHTAG) {
var tags = data.rows.HASHTAG.split('#');
tags.forEach(function(tag) {
var trimmed = tag.trim();
if(trimmed) {
hashtagHtml += '<span class="tag">#' + trimmed + '</span>';
}
});
}
$('.tag-list').html(hashtagHtml);
}else{
modalEvent.danger("조회 오류", data.msgDesc);
}
},
error : function(xhr, status, error) {
modalEvent.danger("조회 오류", "조회 중 오류가 발생하였습니다. 잠시후 다시시도하십시오.");
},
beforeSend:function(){
// 로딩열기
$(".loading-image-layer").show();
},
complete:function(){
// 로딩닫기
$(".loading-image-layer").hide();
}
});
}
function formatDate(dateValue) {
const date = new Date(dateValue);
const yyyy = date.getFullYear();
const mm = String(date.getMonth() + 1).padStart(2, '0');
const dd = String(date.getDate()).padStart(2, '0');
return `${yyyy}-${mm}-${dd}`;
}
// Before-After 슬라이더 기능 (모바일/PC 모두 지원)
const slider = document.getElementById('compare-slider');
const afterImg = slider.querySelector('.after-img');
const bar = slider.querySelector('.slider-bar');
const dot = slider.querySelector('.slider-dot');
const beforeLabel = document.querySelector('.before-label');
const afterLabel = document.querySelector('.after-label');
let dragging = false;
function setSlider(x) {
const rect = slider.getBoundingClientRect();
let pos = Math.max(0, Math.min(x - rect.left, rect.width));
let percent = pos / rect.width * 100;
afterImg.style.clipPath = `inset(0 0 0 ${percent}%)`;
bar.style.left = percent + '%';
dot.style.left = percent + '%';
// 라벨 강조 효과 추가
if (percent < 30) {
// Before 영역 (왼쪽 30% 미만)
beforeLabel.classList.add('active');
afterLabel.classList.remove('active');
} else if (percent > 70) {
// After 영역 (오른쪽 70% 초과)
afterLabel.classList.add('active');
beforeLabel.classList.remove('active');
} else {
// 중간 영역 - 둘 다 비활성화
beforeLabel.classList.remove('active');
afterLabel.classList.remove('active');
}
}
function startDrag(e) {
dragging = true;
document.body.style.userSelect = 'none';
}
function stopDrag() {
dragging = false;
document.body.style.userSelect = '';
}
function onDrag(e) {
if (!dragging) return;
let x = e.touches ? e.touches[0].clientX : e.clientX;
setSlider(x);
}
slider.addEventListener('mousedown', startDrag);
slider.addEventListener('touchstart', startDrag);
window.addEventListener('mousemove', onDrag);
window.addEventListener('touchmove', onDrag);
window.addEventListener('mouseup', stopDrag);
window.addEventListener('touchend', stopDrag);
// 초기값 중앙
setSlider(slider.getBoundingClientRect().width / 2 + slider.getBoundingClientRect().left);
</script>
</th:block>
</html>

View File

@@ -0,0 +1,758 @@
<!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="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss">
<style>
:root {
--main-bg: #f8f9fa;
--card-bg: #ffffff;
--accent: #C60B24;
--text: #1a1a1a;
--muted: #6b7280;
--border: #e9ecef;
--shadow: 0 2px 16px rgba(0,0,0,0.06);
--shadow-hover: 0 8px 32px rgba(0,0,0,0.12);
--radius: 16px;
}
* {
box-sizing: border-box;
}
/* 전체 기본 스타일 */
html, body {
height: 100vh;
margin: 0;
padding: 0;
font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
background: var(--main-bg);
color: var(--text);
overflow-x: hidden;
font-size: 16px;
line-height: 1.6;
}
/* 메인 컨테이너 */
.container {
max-width: 1280px;
width: 100%;
margin: 0 auto;
min-height: calc(100vh - 300px);
display: flex;
flex-direction: column;
gap: 1.5rem;
}
/* 상단 헤더 영역 */
.photo-header {
background: var(--card-bg);
border-radius: var(--radius);
box-shadow: var(--shadow);
padding: 1.0rem 2rem;
border-bottom: 3px solid var(--accent);
flex-shrink: 0;
}
.photo-page-title {
font-size: clamp(1.5rem, 3vw, 1.875rem); /* 24px ~ 30px */
font-weight: 700;
color: var(--text);
margin: 0;
letter-spacing: -0.025em;
}
/* 하단 콘텐츠 영역 (사이드바 + 메인) */
.content-wrapper {
flex: 1;
display: flex;
gap: 1.5rem;
min-height: 0;
}
/* 좌측 사이드바 */
.photo-sidebar {
width: 240px;
min-width: 220px;
flex-shrink: 0;
background: var(--card-bg);
border-radius: var(--radius);
box-shadow: var(--shadow);
height: fit-content;
max-height: 100%;
overflow-y: auto;
position: sticky;
top: 0;
}
.photo-sidebar-title {
padding: 1.25rem 1.5rem;
font-size: 1.125rem; /* 18px */
font-weight: 700;
color: var(--accent);
border-bottom: 1px solid var(--border);
}
.photo-category-list {
list-style: none;
padding: 1rem;
margin: 0;
}
.photo-category-list li {
margin-bottom: 0.375rem;
}
.photo-category-btn {
width: 100%;
background: none;
border: none;
text-align: left;
padding: 0.75rem 1rem;
font-size: 0.95rem; /* 15.2px */
color: var(--muted);
cursor: pointer;
border-radius: 10px;
transition: all 0.2s ease;
}
.photo-category-btn:hover {
background: #f9fafb;
color: var(--accent);
transform: translateX(2px);
}
.photo-category-btn.active {
background: rgba(198, 11, 36, 0.08);
color: var(--accent);
font-weight: 600;
border-left: 4px solid var(--accent);
}
/* 메인 콘텐츠 영역 */
.photo-main-content {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
}
/* 그리드 영역 */
.photo-grid-wrapper {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.photo-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
gap: 1.5rem;
padding-bottom: 2rem;
flex: 1;
}
/* 포토 카드 */
.photo-card {
background: var(--card-bg);
border-radius: var(--radius);
box-shadow: var(--shadow);
overflow: hidden;
transition: all 0.3s ease;
display: flex;
flex-direction: column;
cursor: pointer;
border: 1px solid #f1f5f9;
}
.photo-card:hover {
box-shadow: var(--shadow-hover);
transform: translateY(-4px);
border-color: var(--accent);
}
.photo-images {
display: flex;
gap: 0;
background: #f8f9fa;
border-bottom: 1px solid var(--border);
transition: background 0.2s;
}
.photo-img-box {
flex: 1;
position: relative;
aspect-ratio: 1.2 / 1;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.photo-img-box img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.photo-card:hover .photo-img-box img {
transform: scale(1.03);
}
.photo-label {
position: absolute;
left: 10px;
top: 10px;
background: rgba(0,0,0,0.7);
color: white;
font-size: 0.875rem; /* 14px */
font-weight: 500;
padding: 4px 10px;
border-radius: 6px;
letter-spacing: 0.025em;
z-index: 10;
}
.photo-info {
padding: 1.25rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.photo-title {
font-size: 1.125rem; /* 18px */
font-weight: 600;
margin-bottom: 0.25rem;
color: var(--text);
letter-spacing: -0.025em;
}
.photo-desc {
color: var(--muted);
font-size: 0.9375rem; /* 15px */
line-height: 1.5;
}
/* 페이지네이션 */
.pagination-wrapper {
display: flex;
justify-content: center;
align-items: center;
margin-top: 2rem;
padding: 1.5rem 0;
flex-shrink: 0;
}
.pagination {
display: flex;
gap: 0.5rem;
align-items: center;
}
.pagination-btn {
background: var(--card-bg);
border: 1px solid var(--border);
color: var(--text);
padding: 0.625rem 0.875rem;
border-radius: 8px;
cursor: pointer;
font-size: 0.9375rem; /* 15px */
font-weight: 500;
transition: all 0.2s ease;
min-width: 44px;
text-align: center;
}
.pagination-btn:hover:not(.active):not(.disabled) {
background: #f8f9fa;
border-color: var(--accent);
color: var(--accent);
}
.pagination-btn.active {
background: var(--accent);
border-color: var(--accent);
color: white;
font-weight: 600;
}
.pagination-btn.disabled {
opacity: 0.5;
cursor: not-allowed;
background: #f8f9fa;
}
.pagination-info {
color: var(--muted);
font-size: 0.875rem; /* 14px */
margin: 0 1rem;
}
/* 스크롤바 커스터마이징 */
.photo-grid-wrapper::-webkit-scrollbar,
.photo-sidebar::-webkit-scrollbar {
width: 6px;
}
.photo-grid-wrapper::-webkit-scrollbar-track,
.photo-sidebar::-webkit-scrollbar-track {
background: #f8fafc;
border-radius: 3px;
}
.photo-grid-wrapper::-webkit-scrollbar-thumb,
.photo-sidebar::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 3px;
}
.photo-grid-wrapper::-webkit-scrollbar-thumb:hover,
.photo-sidebar::-webkit-scrollbar-thumb:hover {
background: var(--accent);
}
/* 반응형 디자인 - 태블릿 */
@media (max-width: 1024px) {
.container {
padding: 1rem;
gap: 1rem;
}
.content-wrapper {
gap: 1rem;
}
.photo-sidebar {
width: 220px;
min-width: 200px;
}
.photo-grid {
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 1.25rem;
}
.photo-header {
padding: 1.25rem 1.5rem;
}
.photo-page-title {
font-size: clamp(1.375rem, 2.8vw, 1.75rem); /* 22px ~ 28px */
}
}
/* 반응형 디자인 - 모바일 */
@media (max-width: 768px) {
.container {
flex-direction: column;
padding: 1rem;
gap: 1rem;
}
.content-wrapper {
flex-direction: column;
gap: 1rem;
}
.photo-sidebar {
width: 100%;
position: static;
max-height: none;
order: 1;
}
.photo-category-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 0.5rem;
padding: 1rem;
}
.photo-category-btn {
text-align: center;
padding: 0.75rem 0.5rem;
font-size: 0.875rem; /* 14px */
}
.photo-main-content {
order: 2;
}
.photo-grid {
grid-template-columns: 1fr;
gap: 1rem;
}
/* 모바일에서 이미지는 가로 배치 유지 */
.photo-images {
display: flex;
flex-direction: row;
min-height: 200px;
gap: 2px;
}
.photo-img-box {
flex: 1;
height: 200px;
aspect-ratio: auto;
}
.photo-label {
font-size: 0.75rem; /* 12px */
padding: 3px 6px;
left: 6px;
top: 6px;
}
.photo-header {
padding: 1rem 1.5rem;
border-radius: 12px;
}
.photo-page-title {
font-size: clamp(1.25rem, 2.5vw, 1.5rem); /* 20px ~ 24px */
}
.photo-title {
font-size: 1rem; /* 16px */
}
.photo-desc {
font-size: 0.875rem; /* 14px */
}
.pagination {
flex-wrap: wrap;
gap: 0.375rem;
}
.pagination-btn {
padding: 0.5rem 0.75rem;
font-size: 0.875rem; /* 14px */
min-width: 40px;
}
}
/* 작은 모바일 */
@media (max-width: 480px) {
.container {
padding: 0.75rem;
}
.photo-header {
padding: 0.875rem 1rem;
}
.photo-page-title {
font-size: clamp(1.125rem, 2.2vw, 1.375rem); /* 18px ~ 22px */
}
.photo-images {
min-height: 160px;
}
.photo-img-box {
height: 160px;
}
.photo-info {
padding: 1rem;
}
.photo-title {
font-size: 0.9375rem; /* 15px */
}
.photo-desc {
font-size: 0.8125rem; /* 13px */
}
.pagination-btn {
padding: 0.375rem 0.625rem;
font-size: 0.8125rem; /* 13px */
min-width: 36px;
}
.pagination-info {
font-size: 0.75rem; /* 12px */
}
}
</style>
</th:block>
<th:block layout:fragment="layoutContent">
<div class="container">
<!-- 상단 헤더 영역 -->
<div class="photo-header">
<h1 class="photo-page-title">전후사진 안내</h1>
</div>
<!-- 하단 콘텐츠 영역 (사이드바 + 메인) -->
<div class="content-wrapper">
<!-- 좌측 사이드바 -->
<aside class="photo-sidebar">
<div class="photo-sidebar-title">카테고리</div>
<ul class="photo-category-list" id="category-list">
<li><button class="photo-category-btn active" data-category="전체">전체</button></li>
<li><button class="photo-category-btn" data-category="여드름">여드름</button></li>
<li><button class="photo-category-btn" data-category="잡티/색소">잡티/색소</button></li>
<li><button class="photo-category-btn" data-category="리프팅">리프팅</button></li>
<li><button class="photo-category-btn" data-category="흉터">흉터</button></li>
<li><button class="photo-category-btn" data-category="모공">모공</button></li>
</ul>
</aside>
<!-- 메인 콘텐츠 -->
<main class="photo-main-content">
<div class="photo-grid-wrapper">
<div class="photo-grid" id="photo-grid">
<!-- JS로 게시물 렌더링 -->
</div>
<!-- 페이지네이션 -->
<div class="pagination-wrapper" id="pagination-wrapper">
<div class="pagination" id="pagination">
<!-- JS로 페이지네이션 버튼 렌더링 -->
</div>
</div>
</div>
</main>
</div>
</div>
</th:block>
<th:block layout:fragment="layoutContentScript">
<script th:inline="javascript">
// CDN_URL 전역 정의
const CDN_URL = "[(${@environment.getProperty('url.cdn')})]";
class PhotoGallery {
constructor() {
this.allPosts = [];
this.currentPage = 1;
this.postsPerPage = 6;
this.init();
}
async init() {
await this.loadCategories();
}
async apiRequest(url, data) {
return new Promise((resolve, reject) => {
$.ajax({
url: encodeURI(url),
data: data,
dataType: 'json',
processData: false,
contentType: false,
type: 'POST',
success: resolve,
error: reject,
beforeSend: () => $(".loading-image-layer").show(),
complete: () => $(".loading-image-layer").hide()
});
});
}
async loadCategories() {
try {
const formData = new FormData();
formData.append('bannerType', 'A');
const data = await this.apiRequest('/webphoto/selectListWebPhoto.do', formData);
if (data.msgCode === '0' && data.rows.length > 0) {
this.renderCategories(data.rows);
this.loadPhotos('all');
}
} catch (error) {
modalEvent.danger("조회 오류", "카테고리 조회 중 오류가 발생했습니다.");
}
}
renderCategories(categories) {
const html = [
'<li><button class="photo-category-btn active" id="category_all">전체</button></li>',
...categories.map(cat =>
`<li><button class="photo-category-btn" id="category_${cat.CATEGORY_NO}">${cat.CATEGORY_NM}</button></li>`
)
].join('');
document.getElementById('category-list').innerHTML = html;
document.querySelectorAll('.photo-category-btn').forEach(btn => {
btn.addEventListener('click', () => {
document.querySelectorAll('.photo-category-btn').forEach(b =>
b.classList.remove('active'));
btn.classList.add('active');
this.loadPhotos(btn.id.split('_')[1]);
});
});
}
async loadPhotos(categoryNo) {
try {
const formData = new FormData();
formData.append('category_no', categoryNo);
const data = await this.apiRequest('/webphoto/selectListPhoto.do', formData);
if (data.msgCode === '0') {
this.allPosts = data.rows.map(row => ({
category: row.CATEGORY_NM,
title: row.TITLE,
desc: row.CONTENT,
before: row.BEFORE_PATH ? CDN_URL + row.BEFORE_PATH : '',
after: row.AFTER_PATH ? CDN_URL + row.AFTER_PATH : '',
// 누락된 필드들 추가
categoryDiv: row.CATEGORY_DIV_CD,
categoryNo: row.CATEGORY_NO,
postNo: row.POST_NO
}));
this.currentPage = 1;
this.renderCurrentPage();
}
} catch (error) {
modalEvent.danger("조회 오류", "사진 조회 중 오류가 발생했습니다.");
}
}
renderCurrentPage() {
const totalPages = Math.ceil(this.allPosts.length / this.postsPerPage);
const startIndex = (this.currentPage - 1) * this.postsPerPage;
const endIndex = startIndex + this.postsPerPage;
const currentPosts = this.allPosts.slice(startIndex, endIndex);
this.renderPhotos(currentPosts);
this.renderPagination(totalPages);
}
renderPhotos(posts) {
const grid = document.getElementById('photo-grid');
if (posts.length === 0) {
grid.innerHTML = '<div style="grid-column: 1/-1; text-align: center; color: var(--muted); padding: 3rem;">등록된 전후사진이 없습니다.</div>';
return;
}
const html = posts.map(post => `
<div class="photo-card" onclick="photoGallery.moveToDetail('${post.categoryDiv}', '${post.categoryNo}', '${post.postNo}')">
<div class="photo-images">
<div class="photo-img-box">
<img src="${post.before}" alt="${post.title} - Before">
<div class="photo-label">Before</div>
</div>
<div class="photo-img-box">
<img src="${post.after}" alt="${post.title} - After">
<div class="photo-label">After</div>
</div>
</div>
<div class="photo-info">
<div class="photo-title">${post.title}</div>
<div class="photo-desc">${post.desc}</div>
</div>
</div>
`).join('');
grid.innerHTML = html;
}
renderPagination(totalPages) {
const wrapper = document.getElementById('pagination-wrapper');
const container = document.getElementById('pagination');
if (totalPages <= 1) {
wrapper.style.display = 'none';
return;
}
wrapper.style.display = 'flex';
const buttons = [];
// 이전 버튼
buttons.push(`<button class="pagination-btn ${this.currentPage === 1 ? 'disabled' : ''}"
${this.currentPage > 1 ? `onclick="photoGallery.goToPage(${this.currentPage - 1})"` : ''}></button>`);
// 페이지 번호 버튼들
const maxVisible = 5;
let startPage = Math.max(1, this.currentPage - Math.floor(maxVisible / 2));
let endPage = Math.min(totalPages, startPage + maxVisible - 1);
if (endPage - startPage + 1 < maxVisible) {
startPage = Math.max(1, endPage - maxVisible + 1);
}
if (startPage > 1) {
buttons.push(`<button class="pagination-btn" onclick="photoGallery.goToPage(1)">1</button>`);
if (startPage > 2) {
buttons.push('<span class="pagination-info">...</span>');
}
}
for (let i = startPage; i <= endPage; i++) {
buttons.push(`<button class="pagination-btn ${i === this.currentPage ? 'active' : ''}"
onclick="photoGallery.goToPage(${i})">${i}</button>`);
}
if (endPage < totalPages) {
if (endPage < totalPages - 1) {
buttons.push('<span class="pagination-info">...</span>');
}
buttons.push(`<button class="pagination-btn" onclick="photoGallery.goToPage(${totalPages})">${totalPages}</button>`);
}
// 다음 버튼
buttons.push(`<button class="pagination-btn ${this.currentPage === totalPages ? 'disabled' : ''}"
${this.currentPage < totalPages ? `onclick="photoGallery.goToPage(${this.currentPage + 1})"` : ''}></button>`);
// 페이지 정보
const startItem = (this.currentPage - 1) * this.postsPerPage + 1;
const endItem = Math.min(this.currentPage * this.postsPerPage, this.allPosts.length);
buttons.push(`<span class="pagination-info">${startItem}-${endItem} / ${this.allPosts.length}</span>`);
container.innerHTML = buttons.join('');
}
goToPage(page) {
const totalPages = Math.ceil(this.allPosts.length / this.postsPerPage);
if (page < 1 || page > totalPages) return;
this.currentPage = page;
this.renderCurrentPage();
document.querySelector('.photo-grid').scrollIntoView({ behavior: 'smooth', block: 'start' });
}
moveToDetail(categoryDiv, categoryNo, postNo) {
const form = document.createElement('form');
form.method = 'post';
form.action = '/webphoto/selectPhotoDetailIntro.do';
const fields = [
{ name: 'CATEGORY_DIV_CD', value: categoryDiv },
{ name: 'CATEGORY_NO', value: categoryNo },
{ name: 'POST_NO', value: postNo }
];
fields.forEach(field => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = field.name;
input.value = field.value;
form.appendChild(input);
});
document.body.appendChild(form);
form.submit();
}
}
const photoGallery = new PhotoGallery();
</script>
</th:block>
</html>