Compare commits

..

11 Commits

Author SHA1 Message Date
pjs
3df9096eec 메타 og추가 2026-02-03 12:13:59 +09:00
pjs
b1a427b435 sitemap.xml 생성 2026-01-19 19:14:54 +09:00
pjs
4a764b8295 인스타그램 키 및 url변경 2026-01-19 18:57:38 +09:00
pjs
c0d026f896 index로 변경 2026-01-19 18:48:39 +09:00
pjs
84f062c681 진료시간변경 2025-12-22 22:48:48 +09:00
pjs
7f4aa950be 휴일설정 2025-12-17 21:44:08 +09:00
pjs
029c45a193 휴일설정 2025-12-17 21:42:55 +09:00
pjs
462d8a15de 휴일설정 2025-12-17 21:40:39 +09:00
pjs
bacd1fe401 휴일 수정 2025-12-17 21:32:07 +09:00
pjs
37174437cf ㄴㄴㄴㄴㄴ 2025-12-17 21:22:11 +09:00
pjs
a057cf425e 휴일 수정 2025-12-17 21:11:39 +09:00
9 changed files with 1625 additions and 2499 deletions

View File

@@ -1,6 +1,5 @@
package com.madeuhome.common.ctrl; package com.madeuhome.common.ctrl;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -24,12 +23,13 @@ public class MenuController {
String requestURI = request.getRequestURI(); String requestURI = request.getRequestURI();
// 특정 URL 패턴에만 메뉴 추가 // 특정 URL 패턴에만 메뉴 추가
if (requestURI.endsWith("Intro.do") || requestURI.startsWith("/index") ) { /*
return menuService.getMenuHierarchy("MAIN"); * if (requestURI.endsWith("Intro.do") || requestURI.startsWith("/index") ) {
} * return menuService.getMenuHierarchy("MAIN"); }
*/
return new ArrayList<>(); return menuService.getMenuHierarchy("MAIN");
} }
} }

View File

@@ -5,7 +5,7 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.GetMapping;
@Slf4j @Slf4j
@@ -19,16 +19,16 @@ public class WebHomeController extends ManagerDraftAction{
* @param response * @param response
* @return * @return
*/ */
@RequestMapping(value="/") @GetMapping("/")
public String homeIntro(HttpSession session,HttpServletRequest request) { public String homeIntro(HttpSession session,HttpServletRequest request) {
log.debug("WebHomeController homeIntro START"); log.debug("WebHomeController homeIntro START");
log.debug("WebHomeController homeIntro END"); log.debug("WebHomeController homeIntro END");
return "/intro"; return "/index";
} }
@RequestMapping(value="/index") @GetMapping("/index")
public String homeIndex(HttpSession session,HttpServletRequest request) { public String homeIndex(HttpSession session,HttpServletRequest request) {
log.debug("WebHomeController homeIndex START"); log.debug("WebHomeController homeIndex START");

View File

@@ -36,7 +36,7 @@ public class WebInstagramServiceImpl implements WebInstagramService {
HashMap<String, Object> paramMap) throws Exception { HashMap<String, Object> paramMap) throws Exception {
log.debug("WebInstagramServiceImpl selectListWebInstagram START"); log.debug("WebInstagramServiceImpl selectListWebInstagram START");
HashMap<String, Object> map = new HashMap<String, Object>(); HashMap<String, Object> map = new HashMap<String, Object>();
String apiUrl = "https://graph.instagram.com/" + clientId + "/media?fields=id,caption,media_url,permalink,media_type,thumbnail_url&access_token=" + accessToken; String apiUrl = "https://graph.facebook.com/" + clientId + "/media?fields=id,caption,media_url,permalink,media_type,thumbnail_url&access_token=" + accessToken;
try{ try{
RestTemplate restTemplate = new RestTemplate(); RestTemplate restTemplate = new RestTemplate();
Map<String, Object> response = restTemplate.getForObject(apiUrl, Map.class); Map<String, Object> response = restTemplate.getForObject(apiUrl, Map.class);

View File

@@ -50,4 +50,4 @@ senderPhoneNumber: 025474711
# Instagram 설정 # Instagram 설정
instagram: instagram:
client-id: 17841400162629727 client-id: 17841400162629727
accesstoken: IGAAMzYDUuoLJBZAFRLMUV4V3ZA5RTdIQzNvUmdYQXd6RGpMaGgxbTFQWUJlcmpKZAGlFM29CX20tOE9iSGg4Y1hwdVVHcUVXeS1RQ3dMWVluOEdTdTY4UUh2aFVVR0tGTGhGLVMwWDdkakFtbWJtbnFhQkprMmQxcGsxQjJGZA3pUTQZDZD accesstoken: EAAbtjekAF1EBQaZAZAmZCW8TyAA176J5yD6tFSj4MaZACgROAxGsvvT0cSvPxqLOHR4Bd8EeHSvWAqHZB8nHxurf3s3z0vtXt8sQ4zZBHpEJcnNTWSOvfch7hXv4uOQcfliBZCL6dDhMukAtgmXRHlfJasKDc5cZBcI7AuqNr1BZB0jUAwPC8uMUiIQ8dFjpRbnVyRwZDZD

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,230 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
<loc>https://petit.madeu.co.kr/</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>1.00</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/index</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webintroduction/selectIntroductionHospitalIntro.do</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webintroduction/selectIntroductionStaffIntro.do</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webintroduction/selectIntroductionWayIntro.do</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceIntro.do?categoryNo=4</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=4&amp;postNo=8</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=4&amp;postNo=2</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=4&amp;postNo=3</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=4&amp;postNo=4</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=4&amp;postNo=5</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=4&amp;postNo=6</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=4&amp;postNo=7</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceIntro.do?categoryNo=2</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=2&amp;postNo=3</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=2&amp;postNo=4</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=2&amp;postNo=5</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceIntro.do?categoryNo=3</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=3&amp;postNo=6</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=3&amp;postNo=10</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=3&amp;postNo=11</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceIntro.do?categoryNo=5</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=5&amp;postNo=5</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=5&amp;postNo=6</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=5&amp;postNo=7</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=5&amp;postNo=8</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=5&amp;postNo=9</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceIntro.do?categoryNo=1</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=1&amp;postNo=10</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=1&amp;postNo=3</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=1&amp;postNo=6</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=1&amp;postNo=11</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceIntro.do?categoryNo=6</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=6&amp;postNo=7</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=6&amp;postNo=8</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=6&amp;postNo=9</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=6&amp;postNo=10</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=6&amp;postNo=11</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceIntro.do?categoryNo=7</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=7&amp;postNo=8</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webservice/selectServiceDetailIntro.do?categoryDivCd=03&amp;categoryNo=7&amp;postNo=9</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webevent/selectListWebEventIntro.do</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webphoto/selectListWebPhotoIntro.do</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webaccept/acceptSite.do</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>https://petit.madeu.co.kr/webaccept/acceptPrivacy.do</loc>
<lastmod>2026-01-19T10:12:59+00:00</lastmod>
<priority>0.80</priority>
</url>
</urlset>

View File

@@ -5,8 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <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="keyword" content="HTML, meta, tag, element, reference">
<meta name="author" content="NTSOFT"> <meta name="author" content="VARASOFT">
<meta name="description" content={props.description} data-react-helmet="true" />
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<meta http-equiv="Cache-Control" content="No-Cache" /> <meta http-equiv="Cache-Control" content="No-Cache" />
@@ -16,14 +15,13 @@
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE10"> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE10">
<!-- sns미리보기 --> <!-- sns미리보기 -->
<meta name="description" content="다이어트약, 강남피부과,비만클리닉, 리쥬란힐러,신논현피부과,논현피부과,스컬트라,울쎄라,강남울쎄라,써마지,강남써마지,지방분해주사,윤곽주사">
<meta property="og:type" content="website"> <meta property="og:type" content="website">
<!-- <meta property="og:url" content="https://ntsoft.kr/"> --> <meta property="og:title" content="메이드유의원 강남본점">
<meta property="og:image" content=""> <meta name="og:description" content="다이어트약, 강남피부과,비만클리닉, 리쥬란힐러,신논현피부과,논현피부과,스컬트라,울쎄라,강남울쎄라,써마지,강남써마지,지방분해주사,윤곽주사">
<meta property="og:title" content="메이드유">
<meta property="og:description" content="설명문구">
<!-- 사이트등록및소유확인 --> <!-- 사이트등록및소유확인 -->
<meta name="naver-site-verification" content="" /> <meta name="naver-site-verification" content="8720c03a4463520a0bd0979a3a743ff8ef0d8a03" />
<title>메이드유</title> <title>메이드유</title>

File diff suppressed because it is too large Load Diff

View File

@@ -5,467 +5,7 @@
layout:decorate="~{/web/layout/layout}"> layout:decorate="~{/web/layout/layout}">
<th:block layout:fragment="layoutCss"> <th:block layout:fragment="layoutCss">
<style> <link rel="stylesheet" th:href="@{/css/web/service/makeReservation.css}" />
* {
box-sizing: border-box;
}
body {
font-family: 'Noto Sans KR', sans-serif;
margin: 0;
background: #fafafa;
color: #222;
height: 100vh;
display: flex;
flex-direction: column;
}
/* Main container */
.reservation-container {
display: flex;
max-width: 1280px !important;
margin: 0 auto;
gap: 20px;
height: 100%;
flex: 1;
padding: 20px 0;
margin-top:65px;
}
.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;
height: fit-content;
min-height: 600px;
}
.step-title {
color: #b23c3c;
font-weight: 700;
font-size: 1.1em;
margin-bottom: 12px;
letter-spacing: 0.02em;
transition: color 0.3s ease;
}
.step-title.completed {
color: #008000 !important;
}
/* Service section */
.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;
transition: color 0.3s ease, opacity 0.3s ease;
}
.service-item .del:hover {
color: #ff0000;
}
.service-item .del.disabled {
color: #ccc;
cursor: not-allowed;
opacity: 0.5;
}
.service-item .del.disabled:hover {
color: #ccc;
}
.service-item .price {
font-weight: bold;
color: #b23c3c;
}
/* Service count indicator */
.service-count-info {
font-size: 0.85em;
color: #888;
margin-bottom: 8px;
text-align: center;
padding: 4px 8px;
background: #f8f9fa;
border-radius: 4px;
}
.service-count-info.single {
color: #ff8c00;
background: #fff3e0;
border: 1px solid #ffcc80;
}
.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 section */
.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 */
.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 section */
.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;
transition: border-color 0.3s ease;
}
.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: #ddd;
color: #888;
border: none;
border-radius: 8px;
font-size: 1.1em;
font-weight: bold;
cursor: not-allowed;
transition: all 0.3s ease;
}
.submit-btn.step-progress {
background: linear-gradient(45deg, #ddd, #bbb);
color: #666;
font-size: 0.95em;
}
.submit-btn.ready {
background: #b23c3c;
color: #fff;
cursor: pointer;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.02); }
100% { transform: scale(1); }
}
/* Phone message styles (common.js PhoneValidator용) */
.phone-message {
font-size: 12px;
margin-top: 5px;
padding: 4px 8px;
border-radius: 4px;
font-weight: 500;
transition: all 0.3s ease;
}
.phone-message.error {
color: #ff0000;
background-color: #ffebee;
border: 1px solid #ffcdd2;
}
.phone-message.warning {
color: #ff8c00;
background-color: #fff3e0;
border: 1px solid #ffcc80;
}
.phone-message.success {
color: #008000;
background-color: #f1f8e9;
border: 1px solid #c8e6c9;
}
.phone-message.info {
color: #2196f3;
background-color: #e3f2fd;
border: 1px solid #90caf9;
}
/* Birth date message styles */
.birth-date-message {
font-size: 12px;
margin-top: 5px;
padding: 4px 8px;
border-radius: 4px;
font-weight: 500;
transition: all 0.3s ease;
}
.birth-date-message.error {
color: #ff0000;
background-color: #ffebee;
border: 1px solid #ffcdd2;
}
.birth-date-message.warning {
color: #ff8c00;
background-color: #fff3e0;
border: 1px solid #ffcc80;
}
.birth-date-message.success {
color: #008000;
background-color: #f1f8e9;
border: 1px solid #c8e6c9;
}
.birth-date-message.info {
color: #2196f3;
background-color: #e3f2fd;
border: 1px solid #90caf9;
}
/* Responsive Design */
@media (max-width: 1199.98px) {
.reservation-container {
max-width: 960px !important;
gap: 16px;
padding: 20px 15px;
}
.box {
padding: 20px 14px;
}
}
@media (max-width: 991.98px) {
.reservation-container {
max-width: 720px !important;
flex-direction: column;
gap: 24px;
height: auto;
padding: 20px 15px;
}
.box {
min-height: unset;
min-width: unset;
}
}
@media (max-width: 767.98px) {
.reservation-container {
max-width: 540px !important;
padding: 15px;
gap: 20px;
}
.box {
padding: 16px 12px;
}
.calendar-table th,
.calendar-table td {
width: 1.8em;
height: 1.8em;
}
.time-btn {
min-width: 70px;
font-size: 0.95em;
}
}
@media (max-width: 575.98px) {
.reservation-container {
max-width: 100% !important;
padding: 10px;
gap: 16px;
}
.box {
padding: 16px 8px;
}
.calendar-table th,
.calendar-table td {
width: 1.5em;
height: 1.5em;
font-size: 0.9em;
}
.time-btn {
min-width: 60px;
font-size: 0.9em;
padding: 6px 0;
}
.step-title {
font-size: 1em;
}
.service-item {
font-size: 1em;
}
}
.calendar-table td.disabled {
color: #ccc;
cursor: not-allowed;
pointer-events: none;
background: none !important;
}
.calendar-table td.disabled:hover {
background: none !important;
cursor: not-allowed !important;
}
</style>
</th:block> </th:block>
<th:block layout:fragment="layout_top_script"> <th:block layout:fragment="layout_top_script">
@@ -559,25 +99,32 @@
<th:block layout:fragment="layoutContentScript"> <th:block layout:fragment="layoutContentScript">
<script> <script>
// 비활성화할 특정 날짜들 (YYYY-MM-DD 형식) - 필요에 따라 수정하세요 // 휴일(완전 휴무) 설정
const disabledSpecificDates = [ const disabledSpecificDates = [
'2025-10-03', // 개천절 '2025-12-25', // 크리스마스
'2025-10-04', // 추석연휴 '2026-01-01', // 신정
'2025-10-06', // 추석 // 필요 시 추가
'2025-10-07', // 추석연휴
'2025-10-08', // 추석 대체휴일
'2025-10-09', // 한글날
'2026-01-01', // 신정
// 필요에 따라 날짜 추가
]; ];
// 날짜가 비활성화 목록에 있는지 확인하는 함수 // 단축 진료일 (15:30까지) 설정
const shortWorkingDates = [
'2025-12-24', // 크리스마스 이브
'2025-12-31' // 연말
];
// 날짜가 휴무일인지 확인
function isDateDisabled(date) { function isDateDisabled(date) {
const dateStr = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; const dateStr = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
return disabledSpecificDates.includes(dateStr); return disabledSpecificDates.includes(dateStr);
} }
// 생년월일 검증 클래스 // 단축 근무일인지 확인
function isShortWorkingDate(date) {
const dateStr = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
return shortWorkingDates.includes(dateStr);
}
// 생년월일 검증 클래스 (기존 그대로 유지)
class BirthDateValidator { class BirthDateValidator {
constructor(inputId, options = {}) { constructor(inputId, options = {}) {
this.inputElement = document.getElementById(inputId); this.inputElement = document.getElementById(inputId);
@@ -751,11 +298,12 @@
// 전역 변수 // 전역 변수
let birthDateValidator; let birthDateValidator;
let selectedTreatments = [];
// 초기화 // 초기화
fn_SelectReservation(category_div_cd, category_no, post_no, procedure_id); fn_SelectReservation(category_div_cd, category_no, post_no, procedure_id);
// 개선된 시술 삭제 함수 // 시술 삭제 함수
function removeService(el) { function removeService(el) {
const serviceItems = document.querySelectorAll('.service-item'); const serviceItems = document.querySelectorAll('.service-item');
const serviceCount = serviceItems.length; const serviceCount = serviceItems.length;
@@ -786,7 +334,6 @@
return true; return true;
} }
// 총 금액 업데이트 함수
function updateTotalPrice() { function updateTotalPrice() {
const serviceItems = document.querySelectorAll('.service-item'); const serviceItems = document.querySelectorAll('.service-item');
let totalPrice = 0; let totalPrice = 0;
@@ -800,7 +347,6 @@
document.getElementById('total-price').textContent = totalPrice.toLocaleString() + '원'; document.getElementById('total-price').textContent = totalPrice.toLocaleString() + '원';
} }
// 시술 개수 및 삭제 버튼 상태 업데이트 함수
function updateServiceCount() { function updateServiceCount() {
const serviceItems = document.querySelectorAll('.service-item'); const serviceItems = document.querySelectorAll('.service-item');
const serviceCount = serviceItems.length; const serviceCount = serviceItems.length;
@@ -855,7 +401,6 @@
}); });
agree.addEventListener('change', checkForm); agree.addEventListener('change', checkForm);
// 개선된 checkForm 함수
function checkForm() { function checkForm() {
const name = document.getElementById('customer-name').value.trim(); const name = document.getElementById('customer-name').value.trim();
@@ -955,87 +500,101 @@
} }
} }
// 캘린더 렌더링 - 수요일 및 특정 날짜 비활성화 // 새로운 진료시간 설정
function renderCalendar(year, month) { const diettimes_mon_wed_fri = [
calendarTitle.textContent = `${year}.${(month+1).toString().padStart(2,'0')}`; "10:00","10:30","11:00","11:30","12:00","12:30",
const firstDay = new Date(year, month, 1); "13:00","13:30","14:00","14:30","15:00","15:30",
const lastDay = new Date(year, month+1, 0); "16:00","16:30","17:00","17:30","18:00","18:30"
const now = new Date(); ];
const todayDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
let html = '<thead><tr>'; const diettimes_tue_thu = [
['일','월','화','수','목','금','토'].forEach(d => html += `<th>${d}</th>`); "10:00","10:30","11:00","11:30","12:00","12:30",
html += '</tr></thead><tbody><tr>'; "13:00","13:30","14:00","14:30","15:00","15:30",
"16:00","16:30","17:00","17:30","18:00","18:30",
"19:00","19:30"
];
for(let i = 0; i < firstDay.getDay(); i++) { const diettimes_sat_short = [
html += '<td class="disabled"></td>'; "10:00","10:30","11:00","11:30","12:00","12:30",
} "13:00","13:30","14:00","14:30","15:00","15:30"
];
for(let d = 1; d <= lastDay.getDate(); d++) { // 캘린더 렌더링 (일요일만 휴무)
const dateObj = new Date(year, month, d); function renderCalendar(year, month) {
let classes = []; calendarTitle.textContent = `${year}.${(month+1).toString().padStart(2,'0')}`;
const firstDay = new Date(year, month, 1);
const lastDay = new Date(year, month+1, 0);
const now = new Date();
const todayDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const isPastDate = dateObj < todayDate; let html = '<thead><tr>';
const isWednesday = dateObj.getDay() === 3; ['일','월','화','수','목','금','토'].forEach(d => html += `<th>${d}</th>`);
const isSpecificDisabled = isDateDisabled(dateObj); // 특정 날짜 체크 html += '</tr></thead><tbody><tr>';
if(dateObj.toDateString() === today.toDateString()) classes.push('today'); for(let i = 0; i < firstDay.getDay(); i++) {
if(selectedDate && dateObj.toDateString() === selectedDate.toDateString()) classes.push('selected'); html += '<td class="disabled"></td>';
}
// 과거 날짜, 일요일, 수요일, 특정 비활성화 날짜 모두 체크
if(isPastDate || dateObj.getDay() === 0 || isWednesday || isSpecificDisabled) {
classes.push('disabled');
}
const clickHandler = (isPastDate || dateObj.getDay() === 0 || isWednesday || isSpecificDisabled) ? for(let d = 1; d <= lastDay.getDate(); d++) {
'' : `onclick="selectDate(${year},${month},${d})"`; const dateObj = new Date(year, month, d);
html += `<td class="${classes.join(' ')}" ${clickHandler}>${d}</td>`; let classes = [];
if((firstDay.getDay()+d) % 7 === 0 && d !== lastDay.getDate()) html += '</tr><tr>'; const isPastDate = dateObj < todayDate;
} const isSunday = dateObj.getDay() === 0;
const isHoliday = isDateDisabled(dateObj);
for(let i = (lastDay.getDay()+1) % 7; i && i < 7; i++) { if(dateObj.toDateString() === today.toDateString()) classes.push('today');
html += '<td class="disabled"></td>'; if(selectedDate && dateObj.toDateString() === selectedDate.toDateString()) classes.push('selected');
}
html += '</tr></tbody>'; // ✅ 수요일 완전 제거! 일요일 + 공휴일만 비활성화
calendarTable.innerHTML = html; if(isPastDate || isSunday || isHoliday) {
checkForm(); classes.push('disabled');
} }
// 날짜 선택 - 수요일 및 특정 날짜 체크 추가 const clickHandler = (isPastDate || isSunday || isHoliday) ?
function selectDate(y, m, d) { '' : `onclick="selectDate(${year},${month},${d})"`;
const tempDate = new Date(y, m, d); html += `<td class="${classes.join(' ')}" ${clickHandler}>${d}</td>`;
const now = new Date();
const todayDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
if (tempDate < todayDate) { if((firstDay.getDay()+d) % 7 === 0 && d !== lastDay.getDate()) html += '</tr><tr>';
alert('과거 날짜는 선택할 수 없습니다.'); }
return;
}
if (tempDate.getDay() === 0) { for(let i = (lastDay.getDay()+1) % 7; i && i < 7; i++) {
alert('일요일은 선택할 수 없습니다.'); html += '<td class="disabled"></td>';
return; }
} html += '</tr></tbody>';
calendarTable.innerHTML = html;
checkForm();
}
if (tempDate.getDay() === 3) { function selectDate(y, m, d) {
alert('수요일은 휴원일 입니다.'); const tempDate = new Date(y, m, d);
return; const now = new Date();
} const todayDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
// 특정 비활성화 날짜 체크 추가 if (tempDate < todayDate) {
if (isDateDisabled(tempDate)) { alert('과거 날짜는 선택할 수 없습니다.');
alert('해당 날짜는 예약할 수 없습니다.'); return;
return; }
}
selectedDate = tempDate; if (tempDate.getDay() === 0) {
renderCalendar(y, m); alert('일요일은 휴무일입니다.');
renderTimeSlots(); return;
checkForm(); }
}
// 월 이동 버튼 이벤트 if (isDateDisabled(tempDate)) {
alert('해당 날짜는 휴무일입니다.');
return;
}
// ✅ 수요일 체크 완전 제거!
selectedDate = tempDate;
renderCalendar(y, m);
renderTimeSlots();
checkForm();
}
// 월 이동 버튼
document.getElementById('prev-month').onclick = function() { document.getElementById('prev-month').onclick = function() {
if(selectedMonth === 0) { if(selectedMonth === 0) {
selectedYear--; selectedYear--;
@@ -1059,46 +618,29 @@
renderTimeSlots(); renderTimeSlots();
checkForm(); checkForm();
}; };
// 시간대 정의
const diettimes_mon_fri = [
"10:00","10:30", "11:00","11:30", "12:00","12:30",
"13:00","13:30", "15:00","15:30", "16:00","16:30", "17:00","17:30",
"18:00","18:30"
];
const diettimes_tue_ths = [ // 시간 슬롯 렌더링 (새로운 진료시간 적용)
"10:00","10:30", "11:00","11:30", "12:00","12:30",
"13:00","13:30", "15:00","15:30", "16:00","16:30", "17:00","17:30",
"18:00","18:30", "19:00","19:30"
];
const diettimes_wes_sat = [
"10:00","10:30", "11:00","11:30", "12:00","12:30",
"13:00","13:30", "14:00","14:30", "15:00","15:30"
];
// 시간 슬롯 렌더링 - 수요일 및 특정 날짜 처리
function renderTimeSlots() { function renderTimeSlots() {
let html = ''; let html = '';
let dayOfWeek = selectedDate ? selectedDate.getDay() : null; let dayOfWeek = selectedDate ? selectedDate.getDay() : null;
let slotArr = []; let slotArr = [];
// 일요일, 수요일, 특정 비활성화 날짜는 시간 슬롯을 표시하지 않음 if (!selectedDate || dayOfWeek === 0 || isDateDisabled(selectedDate)) {
if (dayOfWeek === 0 || dayOfWeek === 3 || (selectedDate && isDateDisabled(selectedDate))) {
timeSlots.innerHTML = ''; timeSlots.innerHTML = '';
personCount.textContent = selectedDate ? 1 : '-'; personCount.textContent = selectedDate ? 1 : '-';
return; return;
} }
if (dayOfWeek !== null) { // 요일별 / 특수일별 시간대 설정
if (dayOfWeek === 1 || dayOfWeek === 5) { // 월(1), 금(5) if (isShortWorkingDate(selectedDate)) {
slotArr = diettimes_mon_fri; // 12/24, 12/31 단축 근무: 10:00~15:30
} else if (dayOfWeek === 2 || dayOfWeek === 4) { // 화(2), 목(4) slotArr = diettimes_sat_short;
slotArr = diettimes_tue_ths; } else if ([1,3,5].includes(dayOfWeek)) { // 월(1), 수(3), 금(5)
} else if (dayOfWeek === 6) { // 토(6) slotArr = diettimes_mon_wed_fri; // 10:00~18:30
slotArr = diettimes_wes_sat; } else if ([2,4].includes(dayOfWeek)) { // 화(2), 목(4)
} slotArr = diettimes_tue_thu; // 10:00~19:30
} else if (dayOfWeek === 6) { // 토(6)
slotArr = diettimes_sat_short; // 10:00~15:30
} }
const now = new Date(); const now = new Date();
@@ -1130,7 +672,6 @@
personCount.textContent = selectedDate ? 1 : '-'; personCount.textContent = selectedDate ? 1 : '-';
} }
// 시간 선택 시 selectedTime 설정 및 onClickTime 호출
function selectTimeAndCall(t, el) { function selectTimeAndCall(t, el) {
const now = new Date(); const now = new Date();
const todayDate = new Date(now.getFullYear(), now.getMonth(), now.getDate()); const todayDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
@@ -1157,7 +698,6 @@
checkForm(); checkForm();
} }
// 선택된 날짜를 yyyymmdd 문자열로 반환
function getSelectedDateStr() { function getSelectedDateStr() {
if (!selectedDate) return ''; if (!selectedDate) return '';
const yyyy = selectedDate.getFullYear(); const yyyy = selectedDate.getFullYear();
@@ -1171,10 +711,9 @@
renderTimeSlots(); renderTimeSlots();
} }
// 날짜 선택 초기화 - 일요일, 수요일, 특정 비활성화 날짜 제외 // 초기 날짜 설정 (일요일/공휴일 제외)
let initDate = new Date(today.getFullYear(), today.getMonth(), today.getDate()); let initDate = new Date(today.getFullYear(), today.getMonth(), today.getDate());
// 일요일(0), 수요일(3), 특정 비활성화 날짜이면 다음 날로 이동 while (initDate.getDay() === 0 || isDateDisabled(initDate)) {
while (initDate.getDay() === 0 || initDate.getDay() === 3 || isDateDisabled(initDate)) {
initDate.setDate(initDate.getDate() + 1); initDate.setDate(initDate.getDate() + 1);
} }
selectDate(initDate.getFullYear(), initDate.getMonth(), initDate.getDate()); selectDate(initDate.getFullYear(), initDate.getMonth(), initDate.getDate());
@@ -1195,8 +734,6 @@
checkForm(); checkForm();
}; };
let selectedTreatments = [];
function fn_reservation(){ function fn_reservation(){
let formData = new FormData(); let formData = new FormData();
if (selectedDate) { if (selectedDate) {
@@ -1284,7 +821,7 @@
li.innerHTML = ` li.innerHTML = `
<span>${item.TREATMENT_PROCEDURE_NAME}</span> <span>${item.TREATMENT_PROCEDURE_NAME}</span>
<span> <span>
<span style="text-decoration:line-through; color:#bbb; font-size:0.95em; margin-right:6px;">${item.DISCOUNT_PRICE != null ? (item.PRICE || 0).toLocaleString() : ''}</span> <span style="text-decoration:line-through; color:#bbb; font-size:0.95em; margin-right:6px;">${item.DISCOUNT_PRICE != null ? (item.PRICE || 0).toLocaleString() : ''}</span>
<span class="price">${Number(price).toLocaleString()}원</span> <span class="price">${Number(price).toLocaleString()}원</span>
<span class="del" title="삭제" onclick="removeService(this)">×</span> <span class="del" title="삭제" onclick="removeService(this)">×</span>
</span> </span>
@@ -1297,12 +834,6 @@
} else { } else {
modalEvent.danger("조회 오류", data.msgDesc); modalEvent.danger("조회 오류", data.msgDesc);
} }
var date = new Date();
if(String(new Date()).split(" ") == "Sun") {
date = new Date();
date.setDate(date.getDate() + 1);
}
}, },
error : function(xhr, status, error) { error : function(xhr, status, error) {
modalEvent.danger("조회 오류", "조회 중 오류가 발생하였습니다. 잠시후 다시시도하십시오."); modalEvent.danger("조회 오류", "조회 중 오류가 발생하였습니다. 잠시후 다시시도하십시오.");
@@ -1321,10 +852,10 @@
if (el) el.classList.add('active'); if (el) el.classList.add('active');
let formData = new FormData(); let formData = new FormData();
formData.append('SELECTED_DATE', selectedDate.toString().substr(0, 4) + '-' + selectedDate.toString().substr(4, 2) + '-' + selectedDate.toString().substr(6, 2)); formData.append('SELECTED_DATE', selectedDate);
formData.append('TIME', time); formData.append('TIME', time);
res_date = selectedDate.toString().substr(0, 4) + '-' + selectedDate.toString().substr(4, 2) + '-' + selectedDate.toString().substr(6, 2); res_date = selectedDate;
res_time = time; res_time = time;
$.ajax({ $.ajax({
@@ -1362,7 +893,6 @@
// PhoneValidator 초기화 // PhoneValidator 초기화
try { try {
if (typeof PhoneValidator !== 'undefined' && PhoneValidator.init) { if (typeof PhoneValidator !== 'undefined' && PhoneValidator.init) {
console.log('Initializing PhoneValidator from common.js');
PhoneValidator.init('customer-phone', { PhoneValidator.init('customer-phone', {
showMessage: true, showMessage: true,
realTimeValidation: true, realTimeValidation: true,
@@ -1372,8 +902,6 @@
setTimeout(checkForm, 10); setTimeout(checkForm, 10);
} }
}); });
} else {
console.warn('PhoneValidator not found in common.js');
} }
} catch (e) { } catch (e) {
console.error('PhoneValidator initialization error:', e); console.error('PhoneValidator initialization error:', e);
@@ -1381,7 +909,6 @@
// BirthDateValidator 초기화 // BirthDateValidator 초기화
try { try {
console.log('Initializing BirthDateValidator');
birthDateValidator = new BirthDateValidator('birthDate', { birthDateValidator = new BirthDateValidator('birthDate', {
showMessage: true, showMessage: true,
realTimeValidation: true, realTimeValidation: true,
@@ -1393,16 +920,11 @@
setTimeout(checkForm, 10); setTimeout(checkForm, 10);
} }
}); });
console.log('BirthDateValidator initialized successfully');
} catch (e) { } catch (e) {
console.error('BirthDateValidator initialization error:', e); console.error('BirthDateValidator initialization error:', e);
} }
$('#customer-phone').on('input keyup blur paste', function() { $('#customer-phone, #birthDate').on('input keyup blur paste', function() {
setTimeout(checkForm, 50);
});
$('#birthDate').on('input keyup blur paste', function() {
setTimeout(checkForm, 50); setTimeout(checkForm, 50);
}); });