feat: Implement web event selection and reservation functionality with dedicated UI, styling, and data mapping.
This commit is contained in:
@@ -15,6 +15,8 @@
|
|||||||
<!-- 카테고리 상세 목록 조회 -->
|
<!-- 카테고리 상세 목록 조회 -->
|
||||||
<select id="selectListEvent" parameterType="hashmap" resultType="hashmap">
|
<select id="selectListEvent" parameterType="hashmap" resultType="hashmap">
|
||||||
SELECT A.CATEGORY_DIV_CD, A.CATEGORY_NO, A.POST_NO, TITLE, CONTENT, THUMBNAIL_BOTTOM_TXT, A.HASHTAG, D.FILE_PATH AS THUMBNAIL_PATH,
|
SELECT A.CATEGORY_DIV_CD, A.CATEGORY_NO, A.POST_NO, TITLE, CONTENT, THUMBNAIL_BOTTOM_TXT, A.HASHTAG, D.FILE_PATH AS THUMBNAIL_PATH,
|
||||||
|
DATE_FORMAT(A.EVENT_START_DT, '%Y-%m-%d') AS EVENT_START_DT,
|
||||||
|
DATE_FORMAT(A.EVENT_END_DT, '%Y-%m-%d') AS EVENT_END_DT,
|
||||||
(SELECT MIN(PRICE + VAT) FROM MU_TREATMENT_PROCEDURE_PRICE C
|
(SELECT MIN(PRICE + VAT) FROM MU_TREATMENT_PROCEDURE_PRICE C
|
||||||
LEFT OUTER JOIN HP_CONTENTS_BBS_PROCEDURE B ON A.POST_NO = B.POST_NO AND A.CATEGORY_DIV_CD = B.CATEGORY_DIV_CD AND A.CATEGORY_NO = B.CATEGORY_NO AND B.USE_YN = 'Y'
|
LEFT OUTER JOIN HP_CONTENTS_BBS_PROCEDURE B ON A.POST_NO = B.POST_NO AND A.CATEGORY_DIV_CD = B.CATEGORY_DIV_CD AND A.CATEGORY_NO = B.CATEGORY_NO AND B.USE_YN = 'Y'
|
||||||
WHERE B.MU_TREATMENT_PROCEDURE_ID = C.MU_TREATMENT_PROCEDURE_ID AND C.USE_YN = 'Y') AS PRICE,
|
WHERE B.MU_TREATMENT_PROCEDURE_ID = C.MU_TREATMENT_PROCEDURE_ID AND C.USE_YN = 'Y') AS PRICE,
|
||||||
|
|||||||
@@ -1,435 +1,460 @@
|
|||||||
/* main_img */
|
* {
|
||||||
.project_wrap .same main .main_img .text_box > div { width:50%; }
|
box-sizing: border-box;
|
||||||
.project_wrap .same main .main_img .text_box .right_text_box p { font-size:52px; color:#000; }
|
|
||||||
.project_wrap .same main .main_img .text_box .right_text_box p span { font-weight:700; }
|
|
||||||
.project_wrap .same main .main_img .text_box .left_text_box p { color:#fff; }
|
|
||||||
.project_wrap .same main .main_img .text_box .left_text_box p span { color:#fff; }
|
|
||||||
/* content5 */
|
|
||||||
.project_wrap .same main .content5 { padding-bottom:0; }
|
|
||||||
|
|
||||||
/* 반응형 - 모바일 */
|
|
||||||
@media only screen and (max-width:768px){
|
|
||||||
/* main_img */
|
|
||||||
.project_wrap .same main .content5 { padding-bottom:0; }
|
|
||||||
.project_wrap .same main .main_img .text_box > div { width:100%; }
|
|
||||||
.project_wrap .same main .main_img .text_box .right_text_box { display:none; }
|
|
||||||
.project_wrap .same main .main_img .text_box .left_text_box p br { display:none; }
|
|
||||||
.project_wrap .same main .main_img .text_box .left_text_box p span { color:#000; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
.fix_area {
|
font-family: 'Noto Sans KR', sans-serif;
|
||||||
min-width: 1200px;
|
|
||||||
width: 1200px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-basic {
|
|
||||||
width:120px;
|
|
||||||
height:40px;
|
|
||||||
border: 1px solid #a73439;
|
|
||||||
border-radius:5px;
|
|
||||||
background-color: white;
|
|
||||||
color: #a73439;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clear:after {
|
|
||||||
display: block;
|
|
||||||
visibility: hidden;
|
|
||||||
height: 0;
|
|
||||||
font-size: 0;
|
|
||||||
clear: both;
|
|
||||||
content: "";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.clear > .right {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clear > .left{
|
|
||||||
float:left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-img-size {
|
|
||||||
position: relative;
|
|
||||||
width: 655px;
|
|
||||||
height: 368px;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.img_center img {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
background: #f7f7f9;
|
||||||
|
color: #222;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#service-header {
|
||||||
.thumbnail-bottom-txt {
|
|
||||||
padding-top: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.thumbnail-bottom-txt > span {
|
|
||||||
display: block;
|
|
||||||
color: #6c696a;
|
|
||||||
font-size: 13.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content>.wp60 {
|
|
||||||
width: 60%;
|
|
||||||
}
|
|
||||||
.content>.wp40 {
|
|
||||||
width: 40%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wp10{
|
|
||||||
width:10%;
|
|
||||||
}
|
|
||||||
.wp90{
|
|
||||||
width:90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.content>[class^=wp] {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.consultation-info h2{
|
|
||||||
font-size: 4rem;
|
|
||||||
}
|
|
||||||
.consultation-info p{
|
|
||||||
margin-top: 2rem;
|
|
||||||
font-size:2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.consultation-info .price {
|
|
||||||
display: block;
|
|
||||||
font-size: 3rem;
|
|
||||||
margin-top: 3rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
.price-area .border-line {
|
|
||||||
height: 1px;
|
|
||||||
background-color: #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.hashtag_list{
|
|
||||||
padding: 1rem 0 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hashtag_list span{
|
|
||||||
font-size:1.6rem;
|
|
||||||
color:#a94442;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.procedure-area>.procedure_select_txt{
|
|
||||||
float: left;
|
|
||||||
width: 7rem;
|
|
||||||
line-height: 1.5;
|
|
||||||
padding-top: 0.375rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.procedure-area > .dropdown_area {
|
|
||||||
float: right;
|
|
||||||
width: calc(100% - 7rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
.select_procedure_div {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select_procedure_div .default_item {
|
|
||||||
padding-top: 0.5rem;
|
|
||||||
padding-left: 0.5rem;
|
|
||||||
padding-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select_procedure_div .default_item {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
padding-right: 2.5rem;
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #cb9f76;
|
|
||||||
text-align: left;
|
|
||||||
border-radius: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.option_scrl_wrap {
|
|
||||||
display: none;
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
z-index:1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select_procedure_div.active .option_scrl_wrap {
|
|
||||||
border: 1px solid #76232f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select_service_form.active .default_item:after {
|
|
||||||
border-top-color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.default_item:after {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
right: 1.1em;
|
|
||||||
margin-top: -0.2rem;
|
|
||||||
border: 0.28571428em solid transparent;
|
|
||||||
border-top-color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.optipon_item {
|
|
||||||
padding: 0.4rem 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sepr_wrap {
|
|
||||||
position: relative;
|
|
||||||
min-height: 2.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item_subprice {
|
|
||||||
min-height: 42px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select_procedure_div.active .option_scrl_wrap {
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
right: -1px;
|
|
||||||
left: -1px;
|
|
||||||
background-color: #fff;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cs-checkbox > label.d-block {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.cs-checkbox > label {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
cursor: pointer;
|
|
||||||
padding-left: 30px;
|
|
||||||
margin: 0;
|
|
||||||
line-height: 20px;
|
|
||||||
transition: color .3s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.oi-wrap {
|
|
||||||
display: -webkit-box;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: flex;
|
|
||||||
-webkit-box-pack: justify;
|
|
||||||
-ms-flex-pack: justify;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* .cs-checkbox input[type="checkbox"] { */
|
|
||||||
/* visibility: hidden; */
|
|
||||||
/* display: none; */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* .cs-checkbox > label:before, .cs-radio > .r_visible { */
|
|
||||||
/* border: 1px solid #ccc; */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
input[type="checkbox"] {
|
|
||||||
transform: scale(1.5); /* 크기를 1.5배로 확대 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.idxChk{
|
|
||||||
position:absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cs-checkbox > label:before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 0.8em;
|
|
||||||
border-radius: 0;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.oi-wrap .oi-txt {
|
|
||||||
flex: 0 0 65%;
|
|
||||||
max-width: 65%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option_list {
|
|
||||||
display: block;
|
|
||||||
background: #fff;
|
background: #fff;
|
||||||
max-height: 224px;
|
border-bottom: 1px solid #ececec;
|
||||||
overflow-y: auto;
|
padding: 14px 0 14px 24px;
|
||||||
overflow-x: hidden;
|
font-size: 0.98em;
|
||||||
|
color: #888;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main-wrap {
|
||||||
.oi-wrap .oi-price {
|
max-width: 1280px;
|
||||||
flex: 0 0 35%;
|
margin: 0 auto;
|
||||||
max-width: 35%;
|
background: #fff;
|
||||||
text-align: right;
|
border-radius: 18px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.07);
|
||||||
|
margin-top: 32px;
|
||||||
|
padding: 0 0 32px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.original_price {
|
.top-section {
|
||||||
color: #757575;
|
display: flex;
|
||||||
opacity: 0.7;
|
flex-wrap: wrap;
|
||||||
|
gap: 32px;
|
||||||
|
padding: 32px 32px 0 32px;
|
||||||
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.d-block {
|
.img-box {
|
||||||
display: block;
|
border-radius: 18px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discount_price {
|
.img-box img {
|
||||||
font-family: 'Campton', Sans-serif;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #A73439;
|
|
||||||
}
|
|
||||||
|
|
||||||
.procedure-area:after {
|
|
||||||
display: block;
|
|
||||||
visibility: hidden;
|
|
||||||
height: 0;
|
|
||||||
font-size: 0;
|
|
||||||
clear: both;
|
|
||||||
content: "";
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-procedure{
|
|
||||||
margin-top:20px;
|
|
||||||
position:relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.selected-procedure .selt_info_wrap .info {
|
|
||||||
top: 0.7rem;
|
|
||||||
width: 9.5em;
|
|
||||||
padding-top: 0.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selt_info_wrap .info {
|
|
||||||
position: absolute;
|
|
||||||
top: 0.2rem;
|
|
||||||
right: 0.2rem;
|
|
||||||
width: 8.5em;
|
|
||||||
padding-right: 1rem;
|
|
||||||
padding-top: 0.2em;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
.selt_info_wrap .info button{
|
|
||||||
border:none;
|
|
||||||
background-color:#fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.real_price {
|
|
||||||
font-family: 'Campton', Sans-serif;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #A73439;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-procedure .selt_info_wrap {
|
|
||||||
padding: 0.8rem 0;
|
|
||||||
z-index:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selt_info_wrap {
|
|
||||||
position: relative;
|
|
||||||
min-height: 2.5rem;
|
|
||||||
background-color:#fff;
|
|
||||||
border:1px solid #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-procedure .selt_info_wrap .selt {
|
|
||||||
padding-right: 9.5em;
|
|
||||||
padding-left: 1rem;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.selt_info_wrap .selt {
|
.info-box {
|
||||||
padding-top: 0.3em;
|
flex: 1 1 300px;
|
||||||
padding-right: 8.5em;
|
min-width: 240px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.total-price-area .total {
|
.info-title {
|
||||||
position: relative;
|
font-size: 1.7em;
|
||||||
background-color: #e6e6e6;
|
font-weight: 700;
|
||||||
padding: 25px 25px 60px;
|
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;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 1.1em;
|
||||||
|
margin-bottom: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.total-price-area .total .txt_sub {
|
.total-row .total-label {
|
||||||
color: #222222;
|
color: #888;
|
||||||
font-size: 2rem;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
.total-price-area .total .right strong {
|
|
||||||
font-size: 22px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.total-price-area .total-price-txt {
|
.total-row .total-price {
|
||||||
font-family: 'Campton', Sans-serif;
|
font-weight: bold;
|
||||||
font-weight: 600;
|
color: #b23c3c;
|
||||||
color: #A73439;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.total-price-area .total .bs-txt {
|
.reserve-btn {
|
||||||
position: absolute;
|
width: 100%;
|
||||||
bottom: 17px;
|
padding: 14px 0;
|
||||||
right: 25px;
|
background: #b23c3c;
|
||||||
display: block;
|
|
||||||
margin-top: 4px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #999999;
|
|
||||||
letter-spacing: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.main_btn {
|
|
||||||
text-align: right;
|
|
||||||
margin: 1rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main_btn button {
|
|
||||||
width: 180px;
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.fastrack-btn {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
border: 1px solid #a73439;
|
|
||||||
background-color: #a73439;
|
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.15s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img-content{
|
.reserve-btn:disabled {
|
||||||
background-color: #eee;
|
background: #ddd;
|
||||||
|
color: #888;
|
||||||
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img-area{
|
.desc-section {
|
||||||
padding-top: 70px;
|
margin-top: 36px;
|
||||||
padding-bottom: 200px;
|
padding: 0 32px;
|
||||||
text-align:center;
|
}
|
||||||
|
|
||||||
|
.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 {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 빨간색으로 변경 */
|
||||||
|
.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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,110 +1,495 @@
|
|||||||
/* main_img */
|
* {
|
||||||
.project_wrap .same main .main_img .text_box > div { width:50%; }
|
box-sizing: border-box;
|
||||||
.project_wrap .same main .main_img .text_box .right_text_box p { font-size:52px; color:#000; }
|
}
|
||||||
.project_wrap .same main .main_img .text_box .right_text_box p span { font-weight:700; }
|
|
||||||
.project_wrap .same main .main_img .text_box .left_text_box p { color:#fff; }
|
|
||||||
.project_wrap .same main .main_img .text_box .left_text_box p span { color:#fff; }
|
|
||||||
/* content5 */
|
|
||||||
.project_wrap .same main .content5 { padding-bottom:0; }
|
|
||||||
|
|
||||||
.project_wrap .same aside {background: white; width: 30%; top: 12%;}
|
/* 전체 기본 스타일 */
|
||||||
.project_wrap .same aside ul{position: fixed; left: 5%; width: 19%;}
|
html,
|
||||||
.project_wrap .same aside ul li{margin-bottom: 0.5rem; margin-top: 0px;}
|
body {
|
||||||
.project_wrap .same aside .first {padding-top: 1rem; padding-bottom: 1rem;}
|
height: 100vh;
|
||||||
.project_wrap .same aside .nonactive {border: 1px solid #d8d8d8; background-color: #f9f9fb;}
|
margin: 0;
|
||||||
.project_wrap .same aside .active {border: 1px solid #d8d8d8; color: #a73439; background-color: rgba(118, 35, 47, 0); border-left: 2px solid #a73439;}
|
padding: 0;
|
||||||
.project_wrap .same aside ul a{padding-left: 10px;}
|
font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
|
||||||
.project_wrap .same main {width: 60%; padding-top: 7%;}
|
background: #f8f9fa;
|
||||||
.project_wrap .same main ul{padding-top: 2%; width:102%;}
|
color: #1a1a1a;
|
||||||
.event-card-list > ul { display: block; list-style-type: disc; margin-block-start: 1em; margin-block-end: 1em; padding-inline-start: 40px; unicode-bidi: isolate; }
|
overflow-x: hidden;
|
||||||
.event-card-list > li { margin-bottom: 70px; opacity: 1;}
|
font-size: 16px;
|
||||||
.event-card-list .event-card { display: block; position: relative; width: 775px; height: 196px; padding-right: 10px; margin-left: auto; overflow: hidden;}
|
line-height: 1.6;
|
||||||
.event-card .img_box { position: relative; width: 350px; height: 100%; background-color: black; float: left; overflow: hidden; }
|
|
||||||
.event-card .img_box img { position: absolute; min-width: 100%; min-height: 100%; width: 100%; height: 100%; margin: auto; top: 0; bottom: 0; left: 0; right: 0; opacity: 1; transform: scale(1); transition: .4s ease-out;}
|
|
||||||
.event-card .txt-box { position: relative; padding-top: 115px; width: 343px; height: 100%; float: right;}
|
|
||||||
.event-card .txt-box .tit-txt { position: absolute; left: 0; bottom: 88px;}
|
|
||||||
.txt-box .tit-txt > p { margin: 0; font-size: 22px; font-weight: 500; line-height: 1.3;}
|
|
||||||
.event-card .txt-box > .sub-txt { font-size: 12px;}
|
|
||||||
.one-ellip { position: relative;overflow: hidden; white-space: nowrap; text-overflow: ellipsis; left: 0%; width: 100%;-webkit-transition: left 3s, width 3s; -moz-transition: left 3s, width 3s; transition: left 3s, width 3s;}
|
|
||||||
.event-card .txt-box .ab_cont { padding-top: 10px;}
|
|
||||||
.ab_cont .cost { font-size: 13px; font-weight: 400; color: #7D7971;}
|
|
||||||
del { text-decoration: line-through;}
|
|
||||||
.ab_cont .discount { display: block; font-size: 1rem;}
|
|
||||||
.ab_cont .discount .txt_num { font-size: 1.6em; font-weight: 600; color: #9F2A2A;}
|
|
||||||
.event-card .txt-box .tit-txt:After { content: ''; position: absolute; top: -49px; left: 0; width: 18px; height: 35px; background: center / contain url(https://www.toxnfill2.com/imges/ico-toxnfill-g.png) no-repeat;}
|
|
||||||
.event-card-list .event-card:after { content: ''; position: absolute; bottom: 9px; right: 0; width: 58px; height: 15px; background: center / contain url(https://www.toxnfill2.com/imges/long-arrow-right-g.png) no-repeat;}
|
|
||||||
.add-ticket-btn {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
font-weight: 400;
|
|
||||||
letter-spacing: -0.03em;
|
|
||||||
padding: .35rem 1rem;
|
|
||||||
border: 1px solid #ced4da;
|
|
||||||
border-radius: 50em;
|
|
||||||
transition: 0.2s;
|
|
||||||
background:white;
|
|
||||||
}
|
}
|
||||||
.right { float: right;}
|
|
||||||
.left { float: left;}
|
/* 메인 컨테이너 */
|
||||||
.card_otxt {
|
.container {
|
||||||
position: relative;
|
max-width: 1280px;
|
||||||
display: block;
|
width: 100%;
|
||||||
border-radius: 1rem;
|
margin: 0 auto;
|
||||||
padding: 1rem;
|
min-height: calc(100vh - 300px);
|
||||||
}
|
|
||||||
.border {
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
}
|
|
||||||
.__card_otxt {
|
|
||||||
height: 95px;
|
|
||||||
}
|
|
||||||
.row>.col2 {
|
|
||||||
width: 50%;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
.row.row_padding>.col2, .row.row_padding>.col3, .row.row_padding>.col4, .row.row_padding>.col5 {
|
|
||||||
padding-right: 1rem;
|
|
||||||
padding-left: 1rem;
|
|
||||||
}
|
|
||||||
.row.row_padding {
|
|
||||||
margin-left: -1rem;
|
|
||||||
margin-right: -1rem;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-direction: column;
|
||||||
|
gap: 1.5rem;
|
||||||
}
|
}
|
||||||
.border-b {
|
|
||||||
border-bottom: 1px solid #ddd;
|
/* 상단 헤더 영역 */
|
||||||
height:5%;
|
.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;
|
||||||
}
|
}
|
||||||
.txt_num {
|
|
||||||
font-family: 'Campton', Sans-serif;
|
.page-title {
|
||||||
|
font-size: clamp(1.5rem, 3vw, 1.875rem);
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
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;
|
font-weight: 600;
|
||||||
color: #A73439;
|
border-left: 4px solid #C60B24;
|
||||||
}
|
}
|
||||||
.card_otxt .ab_cont {
|
|
||||||
|
/* 메인 콘텐츠 영역 */
|
||||||
|
.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;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-card:hover {
|
||||||
|
transform: translateY(-4px);
|
||||||
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
|
||||||
|
border-color: #C60B24;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 지난 이벤트 스타일 */
|
||||||
|
.event-card.expired {
|
||||||
|
opacity: 0.6;
|
||||||
|
filter: grayscale(30%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-card.expired:hover {
|
||||||
|
transform: none;
|
||||||
|
box-shadow: 0 2px 16px rgba(0, 0, 0, 0.06);
|
||||||
|
border-color: #9ca3af;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expired-badge {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 1rem;
|
top: 12px;
|
||||||
top: 3.4rem;
|
right: 12px;
|
||||||
width: 8.5em;
|
background: rgba(107, 114, 128, 0.9);
|
||||||
text-align: right;
|
color: #fff;
|
||||||
|
padding: 4px 12px;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 600;
|
||||||
|
z-index: 2;
|
||||||
}
|
}
|
||||||
.card_otxt .fix_cont {
|
|
||||||
padding-right: 11.5rem;
|
.event-img {
|
||||||
|
width: 340px;
|
||||||
|
min-width: 280px;
|
||||||
|
background: #f3f4f6;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.card_otxt .fix_cont p {
|
|
||||||
|
.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;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
color: #1a1a1a;
|
||||||
|
letter-spacing: -0.025em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-desc {
|
||||||
|
color: #6b7280;
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-meta {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: #9ca3af;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-date {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #9ca3af;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-price {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
color: #C60B24;
|
||||||
|
font-weight: 700;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
word-break: keep-all;
|
|
||||||
}
|
}
|
||||||
.mb3{margin-bottom: 3rem;}
|
|
||||||
.mt70{margin-top: 70%;}
|
|
||||||
|
|
||||||
|
/* 로딩 및 에러 메시지 */
|
||||||
/* 반응형 - 모바일 */
|
.loading {
|
||||||
@media only screen and (max-width:768px){
|
text-align: center;
|
||||||
/* main_img */
|
padding: 2rem;
|
||||||
.project_wrap .same main .content5 { padding-bottom:0; }
|
color: #6b7280;
|
||||||
.project_wrap .same main .main_img .text_box > div { width:100%; }
|
font-size: 0.9375rem;
|
||||||
.project_wrap .same main .main_img .text_box .right_text_box { display:none; }
|
|
||||||
.project_wrap .same main .main_img .text_box .left_text_box p br { display:none; }
|
|
||||||
.project_wrap .same main .main_img .text_box .left_text_box p span { color:#000; }
|
|
||||||
.project_wrap .same main {width: 100%;}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
text-align: center;
|
||||||
|
padding: 2rem;
|
||||||
|
color: #dc2626;
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 레이어 팝업 */
|
||||||
|
.popup-overlay {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 9999;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-overlay.active {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-content {
|
||||||
|
background: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 2rem 2.5rem;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0 8px 40px rgba(0, 0, 0, 0.2);
|
||||||
|
max-width: 400px;
|
||||||
|
width: 90%;
|
||||||
|
animation: popupIn 0.25s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes popupIn {
|
||||||
|
from {
|
||||||
|
transform: scale(0.9);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-icon {
|
||||||
|
font-size: 3rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-title {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1a1a1a;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-message {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: #6b7280;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-close-btn {
|
||||||
|
background: #C60B24;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 0.75rem 2rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-close-btn:hover {
|
||||||
|
background: #a5091e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 스크롤바 커스터마이징 */
|
||||||
|
.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 반응형 디자인 - 모바일 */
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-title {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-price {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 작은 모바일 */
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.container {
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
padding: 0.875rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
font-size: clamp(1.125rem, 2.2vw, 1.375rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-info {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-title {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-desc {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,236 +1,291 @@
|
|||||||
/************************************************
|
// 전역 변수
|
||||||
* 초기화
|
let procedureChoices;
|
||||||
************************************************/
|
let priceList = [];
|
||||||
function fn_init() {
|
const totalEl = document.getElementById('total');
|
||||||
fn_SelectDetail(category_div_cd, category_no, post_no);
|
const reserveBtn = document.getElementById('reserve-btn');
|
||||||
|
|
||||||
$("#btn_makeReservation").on("click", function(){
|
// 초기화
|
||||||
fn_moveReservation(category_div_cd, category_no, post_no);
|
fn_SelectDetail(category_div_cd, category_no, post_no);
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* 카테고리 목록 가져오기
|
* 카테고리 목록 가져오기
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
function fn_SelectDetail(category_div_cd, category_no, post_no){
|
function fn_SelectDetail(category_div_cd, category_no, post_no) {
|
||||||
|
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
formData.append('CATEGORY_DIV_CD', category_div_cd);
|
formData.append('CATEGORY_DIV_CD', category_div_cd);
|
||||||
formData.append('CATEGORY_NO', category_no);
|
formData.append('CATEGORY_NO', category_no);
|
||||||
formData.append('POST_NO', post_no);
|
formData.append('POST_NO', post_no);
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: encodeURI('/webevent/selectEventDetail.do'),
|
url: encodeURI('/webevent/selectEventDetail.do'),
|
||||||
data: formData,
|
data: formData,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
processData: false,
|
processData: false,
|
||||||
contentType: false,
|
contentType: false,
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
async: true,
|
async: true,
|
||||||
success: function(data){
|
success: function (data) {
|
||||||
if(data.msgCode=='0'){
|
if (data.msgCode == '0') {
|
||||||
//화면 데이터 변경
|
// 화면 데이터 변경
|
||||||
$('#category_nm').text(data.rows.CATEGORY_NM);
|
|
||||||
$('#title').text(data.rows.TITLE);
|
$('#title').text(data.rows.TITLE);
|
||||||
$('#serviceThumb').attr('src', data.rows.THUMBNAIL_PATH);
|
$('#serviceThumb').attr('src', CDN_URL + data.rows.THUMBNAIL_PATH);
|
||||||
$('#main_title').text(data.rows.TITLE);
|
$('#thumbnail-bottom-txt').text(data.rows.THUMBNAIL_BOTTOM_TXT);
|
||||||
$('.thumbnail-bottom-txt').text(data.rows.THUMBNAIL_BOTTOM_TXT);
|
|
||||||
$('#contents').text(data.rows.CONTENT);
|
$('#contents').text(data.rows.CONTENT);
|
||||||
if(data.rows.PRICE == null || data.rows.PRICE == undefined){
|
|
||||||
$('#startprice').text('0');
|
if (data.rows.PRICE == null || data.rows.PRICE == undefined) {
|
||||||
}else{
|
$('#price').text('0');
|
||||||
$('#startprice').text(data.rows.PRICE.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
|
} else {
|
||||||
}
|
$('#price').text(data.rows.PRICE.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
|
||||||
$('#hashtag').text(data.rows.HASHTAG);
|
|
||||||
$('#contents_path').text(data.rows.THUMBNAIL_BOTTOM_TXT);
|
|
||||||
$('#contents_path').attr('src', data.rows.CONTENTS_PATH);
|
|
||||||
//시술 목록 데이터 입력
|
|
||||||
let totalCount = data.price.length;
|
|
||||||
if (0 < totalCount) {
|
|
||||||
for (let i = 0; i < data.price.length; i++) {
|
|
||||||
let listHTML = '';
|
|
||||||
listHTML += '<li class="optipon_item sepr_wrap">';
|
|
||||||
listHTML += ' <div class="item_subprice">';
|
|
||||||
listHTML += ' <div class="cs-checkbox">';
|
|
||||||
listHTML += ' <input type="checkbox" class="idxChk" id="checkboxID' + i + '">';
|
|
||||||
listHTML += ' <label class="cs-checkbox-label d-block" for="checkboxID' + i + '">';
|
|
||||||
listHTML += ' <div class="oi-wrap">';
|
|
||||||
listHTML += ' <div class="oi-txt">';
|
|
||||||
listHTML += ' <span class="oi-tit-txt">' + data.price[i].TREATMENT_PROCEDURE_NAME;
|
|
||||||
listHTML += ' </span>';
|
|
||||||
listHTML += ' </div>';
|
|
||||||
listHTML += ' <div class="oi-price">';
|
|
||||||
listHTML += ' <del class="original_price d-block">';
|
|
||||||
listHTML += ' <b>';
|
|
||||||
if(data.price[i].DISCOUNT_PRICE == null || data.price[i].DISCOUNT_PRICE == undefined){
|
|
||||||
if(data.price[i].PRICE == null || data.price[i].PRICE == undefined){
|
|
||||||
listHTML += '0';
|
|
||||||
}else{
|
|
||||||
listHTML += (data.price[i].PRICE).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
listHTML += (data.price[i].DISCOUNT_PRICE).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
||||||
}
|
|
||||||
listHTML += '</b>원';
|
|
||||||
listHTML += ' </del>';
|
|
||||||
listHTML += ' <span class="discount_price">';
|
|
||||||
if(data.price[i].DISCOUNT_PRICE == null || data.price[i].DISCOUNT_PRICE == undefined){
|
|
||||||
if(data.price[i].PRICE == null || data.price[i].PRICE == undefined){
|
|
||||||
listHTML += '0';
|
|
||||||
}else{
|
|
||||||
listHTML += (data.price[i].PRICE).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
listHTML += (data.price[i].DISCOUNT_PRICE).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
||||||
}
|
|
||||||
listHTML += '</span>원';
|
|
||||||
listHTML += ' </div>';
|
|
||||||
listHTML += ' </div>';
|
|
||||||
listHTML += ' </label>';
|
|
||||||
listHTML += ' </div>';
|
|
||||||
listHTML += ' </div>';
|
|
||||||
listHTML += '</li>';
|
|
||||||
$(".option_list").append(listHTML);
|
|
||||||
|
|
||||||
$("#checkboxID" + i).change(function(){
|
|
||||||
if($("#checkboxID" + i).is(":checked")){
|
|
||||||
let listHTML2 = '';
|
|
||||||
listHTML2 += '<li class="s_item selt_info_wrap" id="liid' + i + '">';
|
|
||||||
listHTML2 += '<input type="hidden" id="procedure_id' + i + '" name="procedure_id" value="'+ data.price[i].MU_TREATMENT_PROCEDURE_ID + '">';
|
|
||||||
listHTML2 += ' <div class="txt-wrap"> ';
|
|
||||||
listHTML2 += ' <span class="selt">' + data.price[i].TREATMENT_PROCEDURE_NAME;
|
|
||||||
listHTML2 += ' </div>';
|
|
||||||
listHTML2 += ' <div class="info">';
|
|
||||||
listHTML2 += ' <span><span class="real_price">';
|
|
||||||
if(data.price[i].DISCOUNT_PRICE == null || data.price[i].DISCOUNT_PRICE == undefined){
|
|
||||||
if(data.price[i].PRICE == null || data.price[i].PRICE == undefined){
|
|
||||||
listHTML2 += '0';
|
|
||||||
}else{
|
|
||||||
listHTML2 += (data.price[i].PRICE).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
listHTML2 += (data.price[i].DISCOUNT_PRICE).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
||||||
}
|
|
||||||
listHTML2 += '</span>원</span>';
|
|
||||||
listHTML2 += ' <button type="button" onclick="fn_nocheck(' + i + ');"><img src="/image/close-btn.png" alt="삭제" width="13px" height="13px"></button>';
|
|
||||||
listHTML2 += ' </div>';
|
|
||||||
listHTML2 += '</li>';
|
|
||||||
$("#selectEvent1").append(listHTML2);
|
|
||||||
var price = $("#price_div1").text().replace(/,/g, "");
|
|
||||||
var discount_price = '';
|
|
||||||
if(data.price[i].DISCOUNT_PRICE == null || data.price[i].DISCOUNT_PRICE == undefined){
|
|
||||||
if(data.price[i].PRICE == null || data.price[i].PRICE == undefined){
|
|
||||||
discount_price = 0;
|
|
||||||
}else{
|
|
||||||
discount_price = data.price[i].PRICE;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
discount_price = data.price[i].DISCOUNT_PRICE;
|
|
||||||
}
|
|
||||||
price = Number(price) + Number(discount_price);
|
|
||||||
$("#price_div1").text(price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
|
|
||||||
}else{
|
|
||||||
fn_deleteList(i);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}else{
|
|
||||||
listHTML += '<li>';
|
|
||||||
listHTML += '</li>';
|
|
||||||
$(".option_list").html(listHTML);
|
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
modalEvent.danger("조회 오류", data.msgDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
// header 동적 변경
|
||||||
error : function(xhr, status, error) {
|
$('#header-category-nm').text(data.rows.CATEGORY_NM);
|
||||||
modalEvent.danger("조회 오류", "조회 중 오류가 발생하였습니다. 잠시후 다시시도하십시오.");
|
$('#header-title').text(data.rows.TITLE);
|
||||||
},
|
|
||||||
beforeSend:function(){
|
// 해시태그 처리
|
||||||
// 로딩열기
|
var hashtagHtml = '';
|
||||||
$(".loading-image-layer").show();
|
if (data.rows.HASHTAG) {
|
||||||
},
|
var tags = data.rows.HASHTAG.split('#');
|
||||||
complete:function(){
|
tags.forEach(function (tag) {
|
||||||
// 로딩닫기
|
var trimmed = tag.trim();
|
||||||
$(".loading-image-layer").hide();
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function fn_nocheck(num){
|
/****************************************************************************
|
||||||
$("#checkboxID" + num).prop("checked",false);
|
* Choices.js 초기화 및 옵션 업데이트
|
||||||
fn_deleteList(num);
|
****************************************************************************/
|
||||||
|
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 fn_deleteList(num){
|
/****************************************************************************
|
||||||
|
* 총 금액 업데이트 - 개선된 버전
|
||||||
var price = $("#price_div1").text().replace(/,/g, "");
|
****************************************************************************/
|
||||||
var discount_price = $("#liid" + num + " > div.info > span > span").text().replace(/,/g, "");
|
function updateTotalPrice() {
|
||||||
|
if (!procedureChoices) {
|
||||||
price = Number(price) - Number(discount_price);
|
console.log('procedureChoices not initialized');
|
||||||
$("#price_div1").text(price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
|
|
||||||
$("#liid" + num).remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
function fn_moveReservation(category_div, category_no, post_no){
|
|
||||||
let pageMoveForm = document.createElement('form');
|
|
||||||
let obj = document.createElement('input');
|
|
||||||
obj.setAttribute('type', 'hidden');
|
|
||||||
obj.setAttribute('name', 'CATEGORY_DIV_CD');
|
|
||||||
obj.setAttribute('value', "0"+category_div);
|
|
||||||
pageMoveForm.appendChild(obj);
|
|
||||||
|
|
||||||
let obj2 = document.createElement('input');
|
|
||||||
obj2.setAttribute('type', 'hidden');
|
|
||||||
obj2.setAttribute('name', 'CATEGORY_NO');
|
|
||||||
obj2.setAttribute('value', category_no);
|
|
||||||
pageMoveForm.appendChild(obj2);
|
|
||||||
|
|
||||||
let obj3 = document.createElement('input');
|
|
||||||
obj3.setAttribute('type', 'hidden');
|
|
||||||
obj3.setAttribute('name', 'POST_NO');
|
|
||||||
obj3.setAttribute('value', post_no);
|
|
||||||
pageMoveForm.appendChild(obj3);
|
|
||||||
|
|
||||||
let obj4 = document.getElementsByName('procedure_id');
|
|
||||||
var len = obj4.length;
|
|
||||||
if(len == 0){
|
|
||||||
alert('시술이 선택되지 않았습니다.');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var value = '';
|
|
||||||
for(var i = 0; i < len; i++){
|
const selectedValues = procedureChoices.getValue(true);
|
||||||
value += obj4[i].getAttribute('value') + '#';
|
console.log('Selected values:', selectedValues);
|
||||||
}
|
|
||||||
|
let total = 0;
|
||||||
let obj5 = document.createElement('input');
|
|
||||||
obj5.setAttribute('type', 'hidden');
|
selectedValues.forEach(value => {
|
||||||
obj5.setAttribute('name', 'PROCEDURE_ID');
|
const item = priceList.find(p => p.MU_TREATMENT_PROCEDURE_ID == value);
|
||||||
obj5.setAttribute('value', value);
|
console.log('Found item for value', value, ':', item);
|
||||||
pageMoveForm.appendChild(obj5);
|
|
||||||
|
if (item) {
|
||||||
pageMoveForm.setAttribute('method', 'post');
|
const basePrice = (item.PRICE || 0) + (item.VAT || 0);
|
||||||
pageMoveForm.setAttribute('action', '/webservice/selectMakeReservation.do');
|
const discountPrice = item.DISCOUNT_PRICE;
|
||||||
document.body.appendChild(pageMoveForm);
|
|
||||||
|
// 할인가가 있고 더 저렴하면 할인가 사용, 아니면 기본가격 사용
|
||||||
pageMoveForm.submit();
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 버튼 클릭했는지 안했는지 확인 class active */
|
/****************************************************************************
|
||||||
var $selectProcedureDiv = $('.select_procedure_div');
|
* 예약 페이지로 이동
|
||||||
$selectProcedureDiv.click(function(e){
|
****************************************************************************/
|
||||||
e.stopPropagation();
|
function fn_moveReservation(category_div, category_no, post_no) {
|
||||||
$selectProcedureDiv.not(this).removeClass('active'); /*remove buttonactive from the others*/
|
if (!procedureChoices) {
|
||||||
$(this).toggleClass('active'); /*toggle current clicked element*/
|
alert('시술 선택 기능이 초기화되지 않았습니다.');
|
||||||
});
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$(window).on("click", function(){
|
const selectedValues = procedureChoices.getValue(true);
|
||||||
$selectProcedureDiv.removeClass('active');
|
|
||||||
})
|
|
||||||
|
|
||||||
//초기화
|
if (selectedValues.length === 0) {
|
||||||
fn_init();
|
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);
|
||||||
|
});
|
||||||
@@ -1,189 +1,216 @@
|
|||||||
/************************************************
|
class EventManager {
|
||||||
* 초기화
|
constructor() {
|
||||||
************************************************/
|
this.events = [];
|
||||||
function fn_init() {
|
this.categories = [];
|
||||||
fn_SelectListCategory();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
await this.loadCategories();
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
async apiRequest(url, data) {
|
||||||
* 이벤트 카테고리 목록 가져오기
|
return new Promise((resolve, reject) => {
|
||||||
****************************************************************************/
|
$.ajax({
|
||||||
function fn_SelectListCategory(){
|
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()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let formData = new FormData();
|
async loadCategories() {
|
||||||
formData.append('bannerType', 'A');
|
try {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('bannerType', 'A');
|
||||||
|
const data = await this.apiRequest('/webevent/selectListWebEvent.do', formData);
|
||||||
|
|
||||||
$.ajax({
|
if (data.msgCode === '0') {
|
||||||
url: encodeURI('/webevent/selectListWebEvent.do'),
|
this.categories = data.rows;
|
||||||
data: formData,
|
this.renderCategories();
|
||||||
dataType: 'json',
|
if (this.categories.length > 0) {
|
||||||
processData: false,
|
this.loadEvents(this.categories[0].CATEGORY_NO);
|
||||||
contentType: false,
|
|
||||||
type: 'POST',
|
|
||||||
async: true,
|
|
||||||
success: function(data){
|
|
||||||
if(data.msgCode=='0'){
|
|
||||||
|
|
||||||
let totalCount = data.rows.length;
|
|
||||||
|
|
||||||
if (0 < totalCount) {
|
|
||||||
let listHTML = '';
|
|
||||||
|
|
||||||
for (let i = 0; i < data.rows.length; i++) {
|
|
||||||
if(i == 0){
|
|
||||||
listHTML += '<li class="active" id="category_'+data.rows[i].CATEGORY_NO+'">';
|
|
||||||
listHTML += ' <a href="javascript:fn_SelectEventList(' + data.rows[i].CATEGORY_NO + ');">' + data.rows[i].CATEGORY_NM + '</a>';
|
|
||||||
listHTML += '</li>';
|
|
||||||
}else{
|
|
||||||
listHTML += '<li class="nonactive" id="category_'+data.rows[i].CATEGORY_NO+'">';
|
|
||||||
listHTML += ' <a href="javascript:fn_SelectEventList(' + data.rows[i].CATEGORY_NO + ');">' + data.rows[i].CATEGORY_NM + '</a>';
|
|
||||||
listHTML += '</li>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$("#servicecategory").html(listHTML);
|
|
||||||
fn_SelectEventList(data.rows[0].CATEGORY_NO);
|
|
||||||
}
|
|
||||||
}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 fn_SelectEventList(category_no){
|
|
||||||
$(".active").addClass("nonactive");
|
|
||||||
$(".active").removeClass("active");
|
|
||||||
|
|
||||||
$("#category_"+category_no).removeClass("nonactive");
|
|
||||||
$("#category_"+category_no).addClass("active");
|
|
||||||
|
|
||||||
|
|
||||||
let formData = new FormData();
|
|
||||||
formData.append('category_no', category_no);
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: encodeURI('/webevent/selectListEvent.do'),
|
|
||||||
data: formData,
|
|
||||||
dataType: 'json',
|
|
||||||
processData: false,
|
|
||||||
contentType: false,
|
|
||||||
type: 'POST',
|
|
||||||
async: true,
|
|
||||||
success: function(data){
|
|
||||||
if(data.msgCode=='0'){
|
|
||||||
|
|
||||||
let totalCount = data.rows.length;
|
|
||||||
let listHTML = '';
|
|
||||||
if (0 < totalCount) {
|
|
||||||
for (let i = 0; i < data.rows.length; i++) {
|
|
||||||
listHTML += '<li class="fadeIn">';
|
|
||||||
listHTML += ' <a href="javascript:fn_moveDetail(' + data.rows[i].CATEGORY_DIV_CD +', ' + data.rows[i].CATEGORY_NO + ',' + data.rows[i].POST_NO + ');" class="event-card">';
|
|
||||||
listHTML += ' <div class="img_box">';
|
|
||||||
listHTML += ' <img src="https://intranet.bbgnetworks.com/uploadFiles/T00004/eventImg/20250203144112.png" alt="평일 오후1시-5시 / 피부 이벤트" class="">';
|
|
||||||
listHTML += ' </div>';
|
|
||||||
listHTML += ' <div class="txt-box">';
|
|
||||||
listHTML += ' <!-- BEST/NEW 아이콘 퍼블리싱 -->';
|
|
||||||
listHTML += ' <!-- __tit-best: best아이콘 __tit-new: new아이콘 -->';
|
|
||||||
listHTML += ' <div class="tit-txt">';
|
|
||||||
listHTML += ' <p class="multy-ellip2">' + data.rows[i].TITLE + '</p>';
|
|
||||||
listHTML += ' </div>';
|
|
||||||
listHTML += ' <span class="sub-txt max-line1 one-ellip">' + data.rows[i].THUMBNAIL_BOTTOM_TXT + '</span>';
|
|
||||||
listHTML += ' <div class="ab_cont">';
|
|
||||||
listHTML += ' <span class="cost"><del class="">';
|
|
||||||
if(data.rows[i].DISCOUNT_PRICE == null || data.rows[i].DISCOUNT_PRICE == undefined){
|
|
||||||
if(data.rows[i].PRICE == null || data.rows[i].PRICE == undefined){
|
|
||||||
listHTML += '0';
|
|
||||||
}else{
|
|
||||||
listHTML += (data.rows[i].PRICE).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
listHTML += (data.rows[i].DISCOUNT_PRICE).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
||||||
}
|
|
||||||
listHTML += ' </del>원</span>';
|
|
||||||
listHTML += ' <span class="discount">';
|
|
||||||
listHTML += ' <strong class="txt_num">';
|
|
||||||
if(data.rows[i].DISCOUNT_PRICE == null || data.rows[i].DISCOUNT_PRICE == undefined){
|
|
||||||
if(data.rows[i].PRICE == null || data.rows[i].PRICE == undefined){
|
|
||||||
listHTML += '0';
|
|
||||||
}else{
|
|
||||||
listHTML += (data.rows[i].PRICE).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
listHTML += (data.rows[i].DISCOUNT_PRICE).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
||||||
}
|
|
||||||
listHTML += ' </strong>원 부터 </span>';
|
|
||||||
listHTML += ' </div>';
|
|
||||||
listHTML += ' </div>';
|
|
||||||
listHTML += ' </a>';
|
|
||||||
listHTML += '</li>';
|
|
||||||
}
|
|
||||||
$("#detail_list").html(listHTML);
|
|
||||||
|
|
||||||
}else{
|
|
||||||
listHTML += '<li class="mt70">';
|
|
||||||
listHTML += '</li>';
|
|
||||||
$("#detail_list").html(listHTML);
|
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
modalEvent.danger("조회 오류", data.msgDesc);
|
modalEvent.danger("조회 오류", data.msgDesc);
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
modalEvent.danger("조회 오류", "조회 중 오류가 발생하였습니다.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
},
|
async loadEvents(categoryNo) {
|
||||||
error : function(xhr, status, error) {
|
try {
|
||||||
modalEvent.danger("조회 오류", "조회 중 오류가 발생하였습니다. 잠시후 다시시도하십시오.");
|
const formData = new FormData();
|
||||||
},
|
formData.append('category_no', categoryNo);
|
||||||
beforeSend:function(){
|
const data = await this.apiRequest('/webevent/selectListEvent.do', formData);
|
||||||
// 로딩열기
|
|
||||||
$(".loading-image-layer").show();
|
if (data.msgCode === '0') {
|
||||||
},
|
const today = new Date();
|
||||||
complete:function(){
|
today.setHours(0, 0, 0, 0);
|
||||||
// 로딩닫기
|
|
||||||
$(".loading-image-layer").hide();
|
this.events = data.rows.map(row => {
|
||||||
}
|
// 지난 이벤트 판별: EVENT_END_DT가 있고 오늘보다 이전이면 expired
|
||||||
});
|
let isExpired = false;
|
||||||
|
if (row.EVENT_END_DT) {
|
||||||
|
const endDate = new Date(row.EVENT_END_DT);
|
||||||
|
endDate.setHours(23, 59, 59, 999);
|
||||||
|
isExpired = endDate < today;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
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,
|
||||||
|
eventStartDt: row.EVENT_START_DT,
|
||||||
|
eventEndDt: row.EVENT_END_DT,
|
||||||
|
isExpired: isExpired
|
||||||
|
};
|
||||||
|
});
|
||||||
|
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 => {
|
||||||
|
const expiredClass = event.isExpired ? ' expired' : '';
|
||||||
|
const expiredBadge = event.isExpired ? '<span class="expired-badge">종료된 이벤트</span>' : '';
|
||||||
|
|
||||||
|
// 이벤트 기간 표시
|
||||||
|
let dateHtml = '';
|
||||||
|
if (event.eventStartDt || event.eventEndDt) {
|
||||||
|
const startStr = event.eventStartDt || '';
|
||||||
|
const endStr = event.eventEndDt || '';
|
||||||
|
if (startStr && endStr) {
|
||||||
|
dateHtml = `<div class="event-date">📅 ${startStr} ~ ${endStr}</div>`;
|
||||||
|
} else if (endStr) {
|
||||||
|
dateHtml = `<div class="event-date">📅 ~ ${endStr}</div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="event-card${expiredClass}" data-category-div="${event.categoryDiv}"
|
||||||
|
data-category-no="${event.categoryNo}" data-post-no="${event.postNo}"
|
||||||
|
data-expired="${event.isExpired}">
|
||||||
|
${expiredBadge}
|
||||||
|
<div class="event-img">
|
||||||
|
<img src="${event.img}" alt="${event.title}">
|
||||||
|
</div>
|
||||||
|
<div class="event-info">
|
||||||
|
<div class="event-title">${event.title}</div>
|
||||||
|
${event.meta ? `<div class="event-meta">${event.meta}</div>` : ''}
|
||||||
|
${dateHtml}
|
||||||
|
<div class="event-price">
|
||||||
|
${event.price.before !== event.price.after
|
||||||
|
? `<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 isExpired = card.dataset.expired === 'true';
|
||||||
|
|
||||||
|
if (isExpired) {
|
||||||
|
// 지난 이벤트 → 팝업 표시
|
||||||
|
this.showExpiredPopup();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const categoryDiv = card.dataset.categoryDiv;
|
||||||
|
const categoryNo = card.dataset.categoryNo;
|
||||||
|
const postNo = card.dataset.postNo;
|
||||||
|
this.goToDetail(categoryDiv, categoryNo, postNo);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
showExpiredPopup() {
|
||||||
|
const overlay = document.getElementById('expired-popup');
|
||||||
|
if (overlay) {
|
||||||
|
overlay.classList.add('active');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hideExpiredPopup() {
|
||||||
|
const overlay = document.getElementById('expired-popup');
|
||||||
|
if (overlay) {
|
||||||
|
overlay.classList.remove('active');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
goToDetail(categoryDiv, categoryNo, postNo) {
|
||||||
|
const form = document.createElement('form');
|
||||||
|
form.method = 'get';
|
||||||
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fn_moveDetail(category_div, category_no, post_no){
|
const eventManager = new EventManager();
|
||||||
let pageMoveForm = document.createElement('form');
|
|
||||||
let obj = document.createElement('input');
|
|
||||||
obj.setAttribute('type', 'hidden');
|
|
||||||
obj.setAttribute('name', 'CATEGORY_DIV_CD');
|
|
||||||
obj.setAttribute('value', "0"+category_div);
|
|
||||||
pageMoveForm.appendChild(obj);
|
|
||||||
|
|
||||||
let obj2 = document.createElement('input');
|
|
||||||
obj2.setAttribute('type', 'hidden');
|
|
||||||
obj2.setAttribute('name', 'CATEGORY_NO');
|
|
||||||
obj2.setAttribute('value', category_no);
|
|
||||||
pageMoveForm.appendChild(obj2);
|
|
||||||
|
|
||||||
let obj3 = document.createElement('input');
|
|
||||||
obj3.setAttribute('type', 'hidden');
|
|
||||||
obj3.setAttribute('name', 'POST_NO');
|
|
||||||
obj3.setAttribute('value', post_no);
|
|
||||||
pageMoveForm.appendChild(obj3);
|
|
||||||
|
|
||||||
pageMoveForm.setAttribute('method', 'post');
|
|
||||||
pageMoveForm.setAttribute('action', '/webevent/selectEventDetailIntro.do');
|
|
||||||
document.body.appendChild(pageMoveForm);
|
|
||||||
pageMoveForm.submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
//초기화
|
|
||||||
fn_init();
|
|
||||||
@@ -1,432 +1,21 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{/web/layout/layout}">
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{/web/layout/layout}">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<th:block layout:fragment="layoutCss">
|
<th:block layout:fragment="layoutCss">
|
||||||
<!-- Choices.js CSS -->
|
<!-- Choices.js CSS -->
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/choices.js/10.2.0/choices.min.css" />
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/choices.js/10.2.0/choices.min.css" />
|
||||||
|
<link rel="stylesheet" th:href="@{/css/web/webevent/webEventSelect.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>
|
||||||
|
|
||||||
<th:block layout:fragment="layout_top_script">
|
<th:block layout:fragment="layout_top_script">
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
let category_div_cd = [[${CATEGORY_DIV_CD}]];
|
let category_div_cd = [[${ CATEGORY_DIV_CD }]];
|
||||||
let category_no = [[${CATEGORY_NO}]];
|
let category_no = [[${ CATEGORY_NO }]];
|
||||||
let post_no = [[${POST_NO}]];
|
let post_no = [[${ POST_NO }]];
|
||||||
const CDN_URL = [[${@environment.getProperty('url.cdn')}]];
|
const CDN_URL = [[${@environment.getProperty('url.cdn') }]];
|
||||||
</script>
|
</script>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|
||||||
<th:block layout:fragment="layoutContent">
|
<th:block layout:fragment="layoutContent">
|
||||||
@@ -439,11 +28,11 @@ const CDN_URL = [[${@environment.getProperty('url.cdn')}]];
|
|||||||
<img id="serviceThumb" th:src="${@environment.getProperty('madeu.logo.size800x450')}" alt="썸네일 이미지">
|
<img id="serviceThumb" th:src="${@environment.getProperty('madeu.logo.size800x450')}" alt="썸네일 이미지">
|
||||||
<pre id="thumbnail-bottom-txt"></pre>
|
<pre id="thumbnail-bottom-txt"></pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="info-box">
|
<div class="info-box">
|
||||||
<div class="info-title" id="title">메쉬다 D/S</div>
|
<div class="info-title" id="title">메쉬다 D/S</div>
|
||||||
<div class="info-desc" id="contents">전신 라인 정리에 특화된 메쉬다 바디주사!</div>
|
<div class="info-desc" id="contents">전신 라인 정리에 특화된 메쉬다 바디주사!</div>
|
||||||
|
|
||||||
<div class="hashtag-section">
|
<div class="hashtag-section">
|
||||||
<div class="hashtag-container">
|
<div class="hashtag-container">
|
||||||
<div class="hashtag-list">
|
<div class="hashtag-list">
|
||||||
@@ -458,14 +47,14 @@ const CDN_URL = [[${@environment.getProperty('url.cdn')}]];
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="info-price"><span id="price">0</span>원 부터</div>
|
<div class="info-price"><span id="price">0</span>원 부터</div>
|
||||||
|
|
||||||
<div class="select-row">
|
<div class="select-row">
|
||||||
<label for="procedure-select">시술 선택</label>
|
<label for="procedure-select">시술 선택</label>
|
||||||
<select id="procedure-select" multiple></select>
|
<select id="procedure-select" multiple></select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="total-row">
|
<div class="total-row">
|
||||||
<span class="total-label">총 금액</span>
|
<span class="total-label">총 금액</span>
|
||||||
<span class="total-price" id="total">0원</span>
|
<span class="total-price" id="total">0원</span>
|
||||||
@@ -473,7 +62,7 @@ const CDN_URL = [[${@environment.getProperty('url.cdn')}]];
|
|||||||
<button class="reserve-btn" id="reserve-btn" disabled>시술 예약하기</button>
|
<button class="reserve-btn" id="reserve-btn" disabled>시술 예약하기</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="desc-section">
|
<div class="desc-section">
|
||||||
<!-- <div class="desc-content">
|
<!-- <div class="desc-content">
|
||||||
<img id="contents_path" th:src="${@environment.getProperty('madeu.logo.size800x450')}" alt="컨텐츠 이미지" width="100%" />
|
<img id="contents_path" th:src="${@environment.getProperty('madeu.logo.size800x450')}" alt="컨텐츠 이미지" width="100%" />
|
||||||
</div> -->
|
</div> -->
|
||||||
@@ -482,301 +71,9 @@ const CDN_URL = [[${@environment.getProperty('url.cdn')}]];
|
|||||||
</th:block>
|
</th:block>
|
||||||
|
|
||||||
<th:block layout:fragment="layoutContentScript">
|
<th:block layout:fragment="layoutContentScript">
|
||||||
<!-- Choices.js JavaScript -->
|
<!-- Choices.js JavaScript -->
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/choices.js/10.2.0/choices.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/choices.js/10.2.0/choices.min.js"></script>
|
||||||
|
<script th:src="@{/js/web/webevent/webEventSelect.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>
|
</th:block>
|
||||||
</html>
|
|
||||||
|
</html>
|
||||||
@@ -1,595 +1,56 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{/web/layout/layout}">
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{/web/layout/layout}">
|
|
||||||
<th:block layout:fragment="layoutCss">
|
<th:block layout:fragment="layoutCss">
|
||||||
<style>
|
<link rel="stylesheet" th:href="@{/css/web/webevent/webEventSelectList.css}" />
|
||||||
* {
|
|
||||||
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>
|
||||||
|
|
||||||
<th:block layout:fragment="layout_top_script">
|
<th:block layout:fragment="layout_top_script">
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
const CDN_URL = [[${@environment.getProperty('url.cdn')}]];
|
const CDN_URL = [[${@environment.getProperty('url.cdn') }]];
|
||||||
</script>
|
</script>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|
||||||
<th:block layout:fragment="layoutContent">
|
<th:block layout:fragment="layoutContent">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<!-- 상단 헤더 영역 -->
|
<!-- 상단 헤더 영역 -->
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<h1 class="page-title">이벤트 안내</h1>
|
<h1 class="page-title">이벤트 안내</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 하단 콘텐츠 영역 (사이드바 + 메인) -->
|
<!-- 하단 콘텐츠 영역 (사이드바 + 메인) -->
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<!-- 좌측 사이드바 -->
|
<!-- 좌측 사이드바 -->
|
||||||
<aside class="sidebar">
|
<aside class="sidebar">
|
||||||
<!--<div class="sidebar-header">이벤트</div>-->
|
<ul class="category-list" id="category-list">
|
||||||
<ul class="category-list" id="category-list">
|
<!-- 카테고리 JS로 렌더링 -->
|
||||||
<!-- 카테고리 JS로 렌더링 -->
|
</ul>
|
||||||
</ul>
|
</aside>
|
||||||
</aside>
|
|
||||||
|
<!-- 메인 콘텐츠 -->
|
||||||
<!-- 메인 콘텐츠 -->
|
<main class="main-content">
|
||||||
<main class="main-content">
|
<div class="event-list">
|
||||||
<div class="event-list">
|
<div class="event-grid" id="event-grid">
|
||||||
<div class="event-grid" id="event-grid">
|
<!-- 이벤트 카드 JS로 렌더링 -->
|
||||||
<!-- 이벤트 카드 JS로 렌더링 -->
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</main>
|
||||||
</main>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 지난 이벤트 레이어 팝업 -->
|
||||||
|
<div class="popup-overlay" id="expired-popup">
|
||||||
|
<div class="popup-content">
|
||||||
|
<div class="popup-icon">⏰</div>
|
||||||
|
<div class="popup-title">지난 이벤트</div>
|
||||||
|
<div class="popup-message">이 이벤트는 종료되었습니다.<br>다른 진행 중인 이벤트를 확인해 주세요.</div>
|
||||||
|
<button class="popup-close-btn" onclick="eventManager.hideExpiredPopup()">확인</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|
||||||
<th:block layout:fragment="layoutContentScript">
|
<th:block layout:fragment="layoutContentScript">
|
||||||
<script>
|
<script th:src="@{/js/web/webevent/webEventSelectList.js}"></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>
|
|
||||||
${event.meta ? `<div class="event-meta">${event.meta}</div>` : ''}
|
|
||||||
<div class="event-price">
|
|
||||||
${event.price.before !== event.price.after
|
|
||||||
? `<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 = 'get';
|
|
||||||
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>
|
</th:block>
|
||||||
</html>
|
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user