웹 서브페이지 UI 레이아웃 작업진행
This commit is contained in:
parent
746a8c5876
commit
d66aded096
49
config/web.php
Normal file
49
config/web.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'hero_slides' => [
|
||||||
|
[
|
||||||
|
'kicker' => 'PIN FOR YOU',
|
||||||
|
'title' => '안전하고 빠른 상품권 거래',
|
||||||
|
'desc' => '구글플레이·문화상품권·편의점 등 인기 상품을 할인 구매하세요.',
|
||||||
|
'cta_label' => '상품 보러가기',
|
||||||
|
'cta_url' => '/shop',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'kicker' => 'EVENT',
|
||||||
|
'title' => '카드/휴대폰 결제 지원',
|
||||||
|
'desc' => '원하는 결제수단으로 편하게, 발송은 빠르게.',
|
||||||
|
'cta_label' => '결제 안내',
|
||||||
|
'cta_url' => '/guide',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'kicker' => 'SUPPORT',
|
||||||
|
'title' => '문제 생기면 1:1 문의',
|
||||||
|
'desc' => '빠른 응답으로 도와드릴게요.',
|
||||||
|
'cta_label' => '1:1 문의하기',
|
||||||
|
'cta_url' => '/cs/qna',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
'cs_tabs' => [
|
||||||
|
['label' => '공지사항', 'route' => 'web.cs.notice.index', 'key' => 'notice'],
|
||||||
|
['label' => '자주 묻는 질문', 'route' => 'web.cs.faq.index', 'key' => 'faq'],
|
||||||
|
['label' => '카카오톡상담', 'route' => 'web.cs.kakao.index', 'key' => 'kakao'],
|
||||||
|
['label' => '1:1 문의', 'route' => 'web.cs.qna.index', 'key' => 'qna'],
|
||||||
|
['label' => '이용안내', 'route' => 'web.cs.guide.index', 'key' => 'guide'],
|
||||||
|
],
|
||||||
|
|
||||||
|
'mypage_tabs' => [
|
||||||
|
['label' => '나의정보', 'route' => 'web.mypage.info.index', 'key' => 'info'],
|
||||||
|
['label' => '이용내역', 'route' => 'web.mypage.usage.index', 'key' => 'usage'],
|
||||||
|
['label' => '교환내역', 'route' => 'web.mypage.exchange.index', 'key' => 'exchange'],
|
||||||
|
['label' => '1:1문의내역', 'route' => 'web.mypage.qna.index', 'key' => 'qna'],
|
||||||
|
],
|
||||||
|
|
||||||
|
'policy_tabs' => [
|
||||||
|
['label' => '개인정보처리방침', 'route' => 'web.policy.privacy.index', 'key' => 'privacy'],
|
||||||
|
['label' => '이용약관', 'route' => 'web.policy.terms.index', 'key' => 'terms'],
|
||||||
|
['label' => '이메일무단수집거부', 'route' => 'web.policy.email.index', 'key' => 'email'],
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
||||||
@ -1212,3 +1212,541 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
.notice-link{ grid-template-columns: 44px 1fr; }
|
.notice-link{ grid-template-columns: 44px 1fr; }
|
||||||
.notice-date{ display:none; }
|
.notice-date{ display:none; }
|
||||||
}
|
}
|
||||||
|
/* ===== Subpage Skeleton ===== */
|
||||||
|
.subpage-wrap{ padding: 18px 0 26px; }
|
||||||
|
|
||||||
|
.subpage-header{
|
||||||
|
display:flex;
|
||||||
|
align-items: baseline;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
margin: 40px 0 16px;
|
||||||
|
padding-left:8px;
|
||||||
|
}
|
||||||
|
.subpage-title{
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.3px;
|
||||||
|
color:#0F172A;
|
||||||
|
}
|
||||||
|
.subpage-desc{
|
||||||
|
font-size: 13px;
|
||||||
|
color:#64748B;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow:hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
max-width: 55%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb{ margin-top: 6px; }
|
||||||
|
.breadcrumb-list{
|
||||||
|
display:flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
font-size: 12px;
|
||||||
|
color:#94A3B8;
|
||||||
|
}
|
||||||
|
.breadcrumb-item::after{
|
||||||
|
content:"/";
|
||||||
|
margin-left: 8px;
|
||||||
|
color:#CBD5E1;
|
||||||
|
}
|
||||||
|
.breadcrumb-item:last-child::after{ content:none; }
|
||||||
|
.breadcrumb-link{ color:#64748B; }
|
||||||
|
.breadcrumb-link:hover{ color:#2563EB; }
|
||||||
|
.breadcrumb-current{ color:#475569; font-weight:700; }
|
||||||
|
|
||||||
|
.subpage-grid{
|
||||||
|
display:grid;
|
||||||
|
grid-template-columns: 260px 1fr;
|
||||||
|
gap: 14px;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subpage-tabs{ display:none; }
|
||||||
|
|
||||||
|
.subpage-side{ position: sticky; top: 90px; }
|
||||||
|
|
||||||
|
.content-card{
|
||||||
|
background:#FFFFFF;
|
||||||
|
border: 1px solid #E5E7EB;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 16px;
|
||||||
|
box-shadow: 0 1px 2px rgba(15,23,42,.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* side nav */
|
||||||
|
.subnav--side .subnav-list{
|
||||||
|
background:#FFFFFF;
|
||||||
|
border: 1px solid #E5E7EB;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 10px;
|
||||||
|
display:grid;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
.subnav-link{
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
height: 40px;
|
||||||
|
padding: 0 12px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 800;
|
||||||
|
color:#334155;
|
||||||
|
}
|
||||||
|
.subnav-link:hover{ background:#F8FAFC; }
|
||||||
|
.subnav-link.is-active{
|
||||||
|
background:#EFF6FF;
|
||||||
|
border: 1px solid #BFDBFE;
|
||||||
|
color:#1D4ED8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mobile tabs */
|
||||||
|
.subnav--tabs{
|
||||||
|
display:flex;
|
||||||
|
gap: 8px;
|
||||||
|
overflow-x: auto;
|
||||||
|
scrollbar-width: none;
|
||||||
|
padding-bottom: 6px;
|
||||||
|
}
|
||||||
|
.subnav--tabs::-webkit-scrollbar{ display:none; }
|
||||||
|
|
||||||
|
.subnav-tab{
|
||||||
|
flex: 0 0 auto;
|
||||||
|
height: 36px;
|
||||||
|
padding: 0 14px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
border: 1px solid #E5E7EB;
|
||||||
|
background:#FFFFFF;
|
||||||
|
font-size: 12.5px;
|
||||||
|
font-weight: 900;
|
||||||
|
color:#334155;
|
||||||
|
}
|
||||||
|
.subnav-tab:hover{ background:#F8FAFC; }
|
||||||
|
.subnav-tab.is-active{
|
||||||
|
background:#EFF6FF;
|
||||||
|
border-color:#BFDBFE;
|
||||||
|
color:#1D4ED8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* notice sample page */
|
||||||
|
.list-head{ display:flex; align-items:center; justify-content:space-between; margin-bottom: 10px; }
|
||||||
|
.list-title{ font-size: 14px; font-weight: 900; color:#0F172A; margin:0; }
|
||||||
|
.list-desc{ font-size: 12.5px; color:#64748B; margin-top: 4px; }
|
||||||
|
.list-head{
|
||||||
|
display:flex;
|
||||||
|
align-items: baseline;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-title{
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-desc{
|
||||||
|
margin: 0;
|
||||||
|
text-align: right;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
max-width: 60%;
|
||||||
|
font-size: 12.5px; color:#64748B;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 560px){
|
||||||
|
.list-desc{ display:none; } /* 모바일은 깔끔하게 */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.notice-list2{ display:grid; }
|
||||||
|
.notice-list2 li + li{ border-top: 1px solid #EEF2F7; }
|
||||||
|
.notice-list2 a{
|
||||||
|
display:grid;
|
||||||
|
grid-template-columns: 54px 1fr auto;
|
||||||
|
gap: 10px;
|
||||||
|
align-items:center;
|
||||||
|
padding: 12px 6px;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
.notice-list2 a:hover{ background:#F8FAFC; }
|
||||||
|
|
||||||
|
.n2-tag{
|
||||||
|
height: 20px;
|
||||||
|
display:inline-flex;
|
||||||
|
align-items:center;
|
||||||
|
justify-content:center;
|
||||||
|
padding: 0 10px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 900;
|
||||||
|
background:#EFF6FF;
|
||||||
|
border:1px solid #BFDBFE;
|
||||||
|
color:#1D4ED8;
|
||||||
|
}
|
||||||
|
.n2-tag--info{
|
||||||
|
background:#F1F5F9;
|
||||||
|
border-color:#E2E8F0;
|
||||||
|
color:#334155;
|
||||||
|
}
|
||||||
|
.n2-text{
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 800;
|
||||||
|
color:#334155;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow:hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.n2-date{ font-size: 12px; color:#94A3B8; white-space: nowrap; }
|
||||||
|
|
||||||
|
.n2s-text{
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #2a3647;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow:hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px){
|
||||||
|
.subpage-grid{ grid-template-columns: 1fr; }
|
||||||
|
.subpage-side{ display:none; }
|
||||||
|
.subpage-tabs{ display:block; }
|
||||||
|
.subpage-desc{ max-width: 100%; }
|
||||||
|
}
|
||||||
|
@media (max-width: 560px){
|
||||||
|
.notice-list2 a{ grid-template-columns: 54px 1fr; }
|
||||||
|
.n2-date{ display:none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Sub Hero (compact rolling banner) ===== */
|
||||||
|
.subhero{
|
||||||
|
margin: 8px 0 10px;
|
||||||
|
}
|
||||||
|
.subhero-inner{
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 16px;
|
||||||
|
border: 1px solid #E5E7EB;
|
||||||
|
background: #F8FAFC;
|
||||||
|
height: 160px; /* ✅ 메인보다 낮게 */
|
||||||
|
}
|
||||||
|
.subhero-track{
|
||||||
|
display:flex;
|
||||||
|
height: 100%;
|
||||||
|
transition: transform .45s cubic-bezier(.25,1,.5,1);
|
||||||
|
}
|
||||||
|
.subhero-slide{
|
||||||
|
min-width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-image: var(--bg);
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.subhero-slide::after{
|
||||||
|
content:"";
|
||||||
|
position:absolute; inset:0;
|
||||||
|
background: rgba(255,255,255,.72); /* ✅ 과하지 않게 텍스트 가독 */
|
||||||
|
}
|
||||||
|
.subhero-content{
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
height: 100%;
|
||||||
|
padding: 18px 18px;
|
||||||
|
display:flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
max-width: 720px;
|
||||||
|
}
|
||||||
|
.subhero-kicker{
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: .8px;
|
||||||
|
color: #2563EB;
|
||||||
|
}
|
||||||
|
.subhero-title{
|
||||||
|
margin-top: 6px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 900;
|
||||||
|
color:#0F172A;
|
||||||
|
letter-spacing: -0.3px;
|
||||||
|
}
|
||||||
|
.subhero-desc{
|
||||||
|
margin-top: 6px;
|
||||||
|
font-size: 13px;
|
||||||
|
color:#64748B;
|
||||||
|
}
|
||||||
|
.subhero-cta{
|
||||||
|
margin-top: 10px;
|
||||||
|
display:inline-flex;
|
||||||
|
align-items:center;
|
||||||
|
height: 34px;
|
||||||
|
padding: 0 12px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
border: 1px solid #BFDBFE;
|
||||||
|
background: #EFF6FF;
|
||||||
|
color:#1D4ED8;
|
||||||
|
font-size: 12.5px;
|
||||||
|
font-weight: 900;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
.subhero-cta:hover{ background:#2563EB; border-color:#2563EB; color:#fff; }
|
||||||
|
|
||||||
|
.subhero-arrow{
|
||||||
|
position:absolute; top:50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 34px; height: 34px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
border: 1px solid #E5E7EB;
|
||||||
|
background: rgba(255,255,255,.9);
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 900;
|
||||||
|
color:#0F172A;
|
||||||
|
}
|
||||||
|
.subhero-arrow.prev{ left: 10px; }
|
||||||
|
.subhero-arrow.next{ right: 10px; }
|
||||||
|
|
||||||
|
.subhero-dots{
|
||||||
|
position:absolute; bottom: 10px; left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
display:flex; gap: 6px;
|
||||||
|
}
|
||||||
|
.subhero-dot{
|
||||||
|
width: 7px; height: 7px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
background: rgba(15,23,42,.18);
|
||||||
|
}
|
||||||
|
.subhero-dot.active{ background:#2563EB; transform: scale(1.2); }
|
||||||
|
/* ===== Notice toolbar (no duplicate nav) ===== */
|
||||||
|
.notice-toolbar{
|
||||||
|
display:flex;
|
||||||
|
align-items:flex-start;
|
||||||
|
justify-content:space-between;
|
||||||
|
gap: 12px;
|
||||||
|
margin: 6px 0 14px;
|
||||||
|
padding: 12px 12px;
|
||||||
|
border: 1px solid #E5E7EB;
|
||||||
|
border-radius: 16px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
box-shadow: 0 1px 2px rgba(15,23,42,.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nt-left{
|
||||||
|
min-width: 0;
|
||||||
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nt-pill{
|
||||||
|
width: fit-content;
|
||||||
|
height: 22px;
|
||||||
|
padding: 0 10px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
background: #EFF6FF;
|
||||||
|
border: 1px solid #BFDBFE;
|
||||||
|
color: #1D4ED8;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nt-meta{
|
||||||
|
font-size: 12.5px;
|
||||||
|
color: #64748B;
|
||||||
|
line-height: 1.45;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
max-width: 520px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nt-right{
|
||||||
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
gap: 10px;
|
||||||
|
align-items:flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nt-search{
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nt-search input{
|
||||||
|
width: 280px;
|
||||||
|
height: 38px;
|
||||||
|
padding: 0 12px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
border: 1px solid #E5E7EB;
|
||||||
|
background: #F3F4F6;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.nt-search input:focus{
|
||||||
|
outline: none;
|
||||||
|
border-color: #2563EB;
|
||||||
|
background: #FFFFFF;
|
||||||
|
box-shadow: 0 0 0 2px #EFF6FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nt-search button{
|
||||||
|
height: 38px;
|
||||||
|
padding: 0 12px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
background: #2563EB;
|
||||||
|
color:#fff;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 900;
|
||||||
|
border: 1px solid #2563EB;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nt-filters{
|
||||||
|
display:flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content:flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nt-chip{
|
||||||
|
height: 32px;
|
||||||
|
padding: 0 12px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
border: 1px solid #E5E7EB;
|
||||||
|
background: #FFFFFF;
|
||||||
|
color: #334155;
|
||||||
|
font-size: 12.5px;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
.nt-chip:hover{ background:#F8FAFC; }
|
||||||
|
|
||||||
|
.nt-chip.is-active{
|
||||||
|
background:#EFF6FF;
|
||||||
|
border-color:#BFDBFE;
|
||||||
|
color:#1D4ED8;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px){
|
||||||
|
.notice-toolbar{ flex-direction:column; align-items:stretch; }
|
||||||
|
.nt-meta{ max-width: 100%; white-space: normal; overflow: visible; text-overflow: clip; }
|
||||||
|
.nt-right{ align-items:stretch; }
|
||||||
|
.nt-search input{ width: 100%; }
|
||||||
|
.nt-filters{ justify-content:flex-start; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Hero variants ===== */
|
||||||
|
.hero-slider{ position: relative; overflow: hidden; background: var(--color-bg-section); }
|
||||||
|
.hero-slider--main{ height: 400px; }
|
||||||
|
.hero-slider--compact{ height: 170px; border-radius: 16px; border: 1px solid #E5E7EB; margin: 14px 0 18px; }
|
||||||
|
|
||||||
|
/* track/slide 동일 */
|
||||||
|
.hero-track{ display:flex; height:100%; transition: transform 0.5s cubic-bezier(0.25,1,0.5,1); }
|
||||||
|
.hero-slide{ min-width:100%; height:100%; display:flex; align-items:center; justify-content:center; padding: 0 24px; }
|
||||||
|
|
||||||
|
.hero-content{ max-width: var(--container-width); width:100%; text-align:left; padding: 0 8px; }
|
||||||
|
|
||||||
|
/* ✅ compact에서 타이포/여백만 줄이기 */
|
||||||
|
.hero-slider--compact .hero-slide{ padding: 0 18px; }
|
||||||
|
.hero-slider--compact .hero-title{ font-size: 22px; margin-bottom: 6px; }
|
||||||
|
.hero-slider--compact .hero-desc{ font-size: 13px; margin-bottom: 10px; }
|
||||||
|
.hero-slider--compact .btn.hero-cta{ padding: 8px 14px; font-size: 13px; }
|
||||||
|
|
||||||
|
/* ✅ 왼쪽/오른쪽 화살표 버튼이 컨텐츠를 가리지 않게 여백 확보 */
|
||||||
|
.slider-arrow{
|
||||||
|
position:absolute; top:50%; transform: translateY(-50%);
|
||||||
|
width: 34px; height: 34px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
border: 1px solid #E5E7EB;
|
||||||
|
background: rgba(255,255,255,.9);
|
||||||
|
font-size: 20px; font-weight: 900;
|
||||||
|
display:flex; align-items:center; justify-content:center;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
.slider-arrow.prev{ left: 10px; }
|
||||||
|
.slider-arrow.next{ right: 10px; }
|
||||||
|
|
||||||
|
/* ✅ 컨텐츠 좌우 패딩(화살표 영역만큼) */
|
||||||
|
.hero-slider--compact .hero-content{ padding-left: 44px; padding-right: 44px; }
|
||||||
|
|
||||||
|
/* dots */
|
||||||
|
.dots-container{ position:absolute; bottom: 12px; left:50%; transform: translateX(-50%); display:flex; gap: 8px; z-index:5; }
|
||||||
|
.dot{ width: 8px; height: 8px; border-radius: 50%; background: rgba(0,0,0,0.18); }
|
||||||
|
.dot.active{ background: var(--color-accent-blue); transform: scale(1.15); }
|
||||||
|
|
||||||
|
@media (max-width: 768px){
|
||||||
|
.hero-slider--compact{ height: 150px; }
|
||||||
|
.hero-slider--compact .hero-content{ padding-left: 14px; padding-right: 14px; } /* 모바일에선 화살표가 위에 떠도 괜찮게 */
|
||||||
|
.slider-arrow{ display:none; } /* 모바일은 스와이프/도트로만 */
|
||||||
|
}
|
||||||
|
.subpage-wrap .hero-slider--compact{
|
||||||
|
margin-top: 14px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== List Head (section heading) ===== */
|
||||||
|
.list-head{
|
||||||
|
display:flex;
|
||||||
|
align-items: baseline;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
margin: 6px 0 12px;
|
||||||
|
|
||||||
|
/* 은은한 구획감: 라인 + 여백만 */
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #EEF2F7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-title{
|
||||||
|
margin: 0;
|
||||||
|
font-size: 16px; /* 과하게 크지 않게 */
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.2px;
|
||||||
|
color: #0F172A;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-desc{
|
||||||
|
margin: 0;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #64748B;
|
||||||
|
line-height: 1.2;
|
||||||
|
|
||||||
|
/* 우측 정렬 + 길면 깔끔하게 처리 */
|
||||||
|
text-align: right;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
max-width: 60%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 모바일은 설명 숨기고 더 타이트하게 */
|
||||||
|
@media (max-width: 560px){
|
||||||
|
.list-head{ padding-bottom: 6px; margin: 4px 0 10px; }
|
||||||
|
.list-title{ font-size: 15px; }
|
||||||
|
.list-desc{ display:none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== CS Tabs ===== */
|
||||||
|
.cs-tabs{
|
||||||
|
display:flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin: 10px 0 14px;
|
||||||
|
}
|
||||||
|
.cs-tab{
|
||||||
|
height: 34px;
|
||||||
|
padding: 0 14px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
border: 1px solid #E5E7EB;
|
||||||
|
background:#fff;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 800;
|
||||||
|
color:#334155;
|
||||||
|
}
|
||||||
|
.cs-tab:hover{ background:#F8FAFC; }
|
||||||
|
.cs-tab.is-active{
|
||||||
|
background:#EFF6FF;
|
||||||
|
border-color:#BFDBFE;
|
||||||
|
color:#1D4ED8;
|
||||||
|
}
|
||||||
|
|||||||
@ -125,4 +125,45 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
alert('모바일 메뉴 드로어 열림 (구현 예정)');
|
alert('모바일 메뉴 드로어 열림 (구현 예정)');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Sub Hero Carousel ---
|
||||||
|
(function initSubHero(){
|
||||||
|
const wrap = document.querySelector('.subhero-inner');
|
||||||
|
if(!wrap) return;
|
||||||
|
|
||||||
|
const track = wrap.querySelector('.subhero-track');
|
||||||
|
const slides = wrap.querySelectorAll('.subhero-slide');
|
||||||
|
const prev = wrap.querySelector('.subhero-arrow.prev');
|
||||||
|
const next = wrap.querySelector('.subhero-arrow.next');
|
||||||
|
const dots = wrap.querySelectorAll('.subhero-dot');
|
||||||
|
|
||||||
|
let idx = 0;
|
||||||
|
const total = slides.length;
|
||||||
|
if(total <= 1) return;
|
||||||
|
|
||||||
|
const render = () => {
|
||||||
|
track.style.transform = `translateX(-${idx * 100}%)`;
|
||||||
|
dots.forEach((d,i)=>d.classList.toggle('active', i===idx));
|
||||||
|
};
|
||||||
|
|
||||||
|
const goNext = () => { idx = (idx + 1) % total; render(); };
|
||||||
|
const goPrev = () => { idx = (idx - 1 + total) % total; render(); };
|
||||||
|
|
||||||
|
let t = setInterval(goNext, 6000);
|
||||||
|
|
||||||
|
const reset = () => { clearInterval(t); t = setInterval(goNext, 6000); };
|
||||||
|
|
||||||
|
next?.addEventListener('click', ()=>{ goNext(); reset(); });
|
||||||
|
prev?.addEventListener('click', ()=>{ goPrev(); reset(); });
|
||||||
|
dots.forEach(d => d.addEventListener('click', ()=>{
|
||||||
|
idx = Number(d.dataset.index || 0);
|
||||||
|
render(); reset();
|
||||||
|
}));
|
||||||
|
|
||||||
|
wrap.addEventListener('mouseenter', ()=>clearInterval(t));
|
||||||
|
wrap.addEventListener('mouseleave', ()=>{ t = setInterval(goNext, 6000); });
|
||||||
|
|
||||||
|
render();
|
||||||
|
})();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,8 +13,8 @@
|
|||||||
<a href="/" class="nav-link">HOME</a>
|
<a href="/" class="nav-link">HOME</a>
|
||||||
<a href="/shop" class="nav-link nav-link--exchange">SHOP</a>
|
<a href="/shop" class="nav-link nav-link--exchange">SHOP</a>
|
||||||
{{-- <a href="/exchange" class="nav-link nav-link--exchange">상품권현금교환</a>--}}
|
{{-- <a href="/exchange" class="nav-link nav-link--exchange">상품권현금교환</a>--}}
|
||||||
<a href="/mypage" class="nav-link">마이페이지</a>
|
<a href="/mypage/info" class="nav-link">마이페이지</a>
|
||||||
<a href="/cs" class="nav-link">고객센터</a>
|
<a href="/cs/notice" class="nav-link">고객센터</a>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
29
resources/views/web/cs/faq/index.blade.php
Normal file
29
resources/views/web/cs/faq/index.blade.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@php
|
||||||
|
$pageTitle = '자주 묻는 질문';
|
||||||
|
$pageDesc = '결제/발송/환불 등 자주 문의되는 내용을 빠르게 확인하세요.';
|
||||||
|
|
||||||
|
$breadcrumbs = [
|
||||||
|
['label' => '홈', 'url' => url('/')],
|
||||||
|
['label' => '고객센터', 'url' => url('/cs')],
|
||||||
|
['label' => '자주 묻는 질문', 'url' => url()->current()],
|
||||||
|
];
|
||||||
|
|
||||||
|
$csActive = 'faq';
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@extends('web.layouts.subpage')
|
||||||
|
|
||||||
|
@section('title', '자주 묻는 질문(FAQ) | PIN FOR YOU')
|
||||||
|
@section('meta_description', 'PIN FOR YOU FAQ입니다. 결제/발송/환불/이용 관련 자주 묻는 질문을 확인하세요.')
|
||||||
|
@section('canonical', url('/cs/faq'))
|
||||||
|
|
||||||
|
@section('subcontent')
|
||||||
|
<div class="faq-page">
|
||||||
|
@include('web.partials.content-head', [
|
||||||
|
'title' => 'FAQ',
|
||||||
|
'desc' => '원하시는 항목을 선택해 빠르게 해결해 보세요.'
|
||||||
|
])
|
||||||
|
|
||||||
|
{{-- TODO: FAQ 내용(아코디언/카테고리/검색 등) --}}
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
29
resources/views/web/cs/guide/index.blade.php
Normal file
29
resources/views/web/cs/guide/index.blade.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@php
|
||||||
|
$pageTitle = '이용안내';
|
||||||
|
$pageDesc = '구매부터 발송/환불까지 서비스 이용 방법을 한눈에 안내합니다.';
|
||||||
|
|
||||||
|
$breadcrumbs = [
|
||||||
|
['label' => '홈', 'url' => url('/')],
|
||||||
|
['label' => '고객센터', 'url' => url('/cs')],
|
||||||
|
['label' => '이용안내', 'url' => url()->current()],
|
||||||
|
];
|
||||||
|
|
||||||
|
$csActive = 'guide';
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@extends('web.layouts.subpage')
|
||||||
|
|
||||||
|
@section('title', '이용안내 | PIN FOR YOU')
|
||||||
|
@section('meta_description', 'PIN FOR YOU 이용안내입니다. 상품권 구매/발송/환불 등 이용 방법을 확인하세요.')
|
||||||
|
@section('canonical', url('/cs/guide'))
|
||||||
|
|
||||||
|
@section('subcontent')
|
||||||
|
<div class="guide-page">
|
||||||
|
@include('web.partials.content-head', [
|
||||||
|
'title' => '서비스 이용 안내',
|
||||||
|
'desc' => '주요 흐름(구매 → 결제 → 발송 → 환불)을 기준으로 안내합니다.'
|
||||||
|
])
|
||||||
|
|
||||||
|
{{-- TODO: 이용안내 본문(단계별 가이드/주의사항/정책 링크 등) --}}
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
29
resources/views/web/cs/kakao/index.blade.php
Normal file
29
resources/views/web/cs/kakao/index.blade.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@php
|
||||||
|
$pageTitle = '카카오톡 상담';
|
||||||
|
$pageDesc = '카카오톡으로 빠르고 편하게 문의하실 수 있어요.';
|
||||||
|
|
||||||
|
$breadcrumbs = [
|
||||||
|
['label' => '홈', 'url' => url('/')],
|
||||||
|
['label' => '고객센터', 'url' => url('/cs')],
|
||||||
|
['label' => '카카오톡 상담', 'url' => url()->current()],
|
||||||
|
];
|
||||||
|
|
||||||
|
$csActive = 'kakao';
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@extends('web.layouts.subpage')
|
||||||
|
|
||||||
|
@section('title', '카카오톡 상담 | PIN FOR YOU')
|
||||||
|
@section('meta_description', 'PIN FOR YOU 카카오톡 상담 안내입니다. 운영시간과 상담 절차를 확인하세요.')
|
||||||
|
@section('canonical', url('/cs/kakao'))
|
||||||
|
|
||||||
|
@section('subcontent')
|
||||||
|
<div class="kakao-page">
|
||||||
|
@include('web.partials.content-head', [
|
||||||
|
'title' => '카카오톡 상담 안내',
|
||||||
|
'desc' => '운영시간과 안내사항을 확인하고 빠르게 문의해 주세요.'
|
||||||
|
])
|
||||||
|
|
||||||
|
{{-- TODO: 카카오 채널 링크/QR/운영시간/주의사항 등 --}}
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
66
resources/views/web/cs/notice/index.blade.php
Normal file
66
resources/views/web/cs/notice/index.blade.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
@php
|
||||||
|
$pageTitle = '공지사항';
|
||||||
|
$pageDesc = '서비스 운영 및 결제/발송 관련 안내를 확인하세요.';
|
||||||
|
|
||||||
|
$breadcrumbs = [
|
||||||
|
['label' => '홈', 'url' => url('/')],
|
||||||
|
['label' => '고객센터', 'url' => url('/cs')],
|
||||||
|
['label' => '공지사항', 'url' => url()->current()],
|
||||||
|
];
|
||||||
|
|
||||||
|
// ✅ 이것만 남기면 됨 (탭 목록은 config에서 자동)
|
||||||
|
$csActive = 'notice';
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@extends('web.layouts.subpage')
|
||||||
|
|
||||||
|
@section('title', '공지사항 | PIN FOR YOU')
|
||||||
|
@section('meta_description', 'PIN FOR YOU 공지사항입니다. 운영/결제/발송 관련 최신 안내를 확인하세요.')
|
||||||
|
@section('canonical', url('/cs/notice'))
|
||||||
|
|
||||||
|
@section('subcontent')
|
||||||
|
<div class="notice-page">
|
||||||
|
@include('web.partials.content-head', [
|
||||||
|
'title' => '최신 공지',
|
||||||
|
'desc' => '중요 안내를 빠르게 확인하세요.'
|
||||||
|
])
|
||||||
|
|
||||||
|
<ul class="notice-list2">
|
||||||
|
{{-- TODO: DB 연결 전 더미 --}}
|
||||||
|
<li><a href="/cs/notice/1"><span class="n2-tag">공지</span><span class="n2-text">설 연휴 고객센터 운영 안내</span><time class="n2-date">2026.01.09</time></a></li>
|
||||||
|
<li><a href="/cs/notice/2"><span class="n2-tag n2-tag--info">안내</span><span class="n2-text">휴대폰 결제 점검 안내(일시)</span><time class="n2-date">2026.01.08</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">안내</span><span class="n2-text">핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">안내</span><span class="n2s-text">핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">안내</span><span class="n2s-text">핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">안내</span><span class="n2s-text">핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">안내</span><span class="n2s-text">핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">안내</span><span class="n2s-text">핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">안내</span><span class="n2s-text">핀번호 발송/재발송 정책 안내핀번호 발송/재발송 정책 안내핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">안내</span><span class="n2s-text">핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">발송</span><span class="n2s-text">핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">경고</span><span class="n2s-text">핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">당첨자</span><span class="n2s-text">핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">안내</span><span class="n2s-text">핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">안내</span><span class="n2s-text">핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">안내</span><span class="n2s-text">핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
<li><a href="/cs/notice/3"><span class="n2-tag n2-tag--info">안내</span><span class="n2s-text">핀번호 발송/재발송 정책 안내</span><time class="n2-date">2026.01.06</time></a></li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{-- Notice Toolbar (replace sub-quick) --}}
|
||||||
|
<div class="notice-toolbar" role="search">
|
||||||
|
<div class="nt-left">
|
||||||
|
<span class="nt-meta">운영시간 평일 09:00~18:00 · 긴급 문의는 1:1 문의 이용</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form class="nt-right" action="{{ url('/cs/notice') }}" method="GET">
|
||||||
|
<div class="nt-search">
|
||||||
|
<input type="text" name="q" value="{{ request('q') }}"
|
||||||
|
placeholder="검색"
|
||||||
|
aria-label="공지 검색">
|
||||||
|
<button type="submit" aria-label="검색">검색</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
29
resources/views/web/cs/qna/index.blade.php
Normal file
29
resources/views/web/cs/qna/index.blade.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@php
|
||||||
|
$pageTitle = '1:1 문의';
|
||||||
|
$pageDesc = '개인 문의는 1:1로 남겨주시면 순차적으로 답변드립니다.';
|
||||||
|
|
||||||
|
$breadcrumbs = [
|
||||||
|
['label' => '홈', 'url' => url('/')],
|
||||||
|
['label' => '고객센터', 'url' => url('/cs')],
|
||||||
|
['label' => '1:1 문의', 'url' => url()->current()],
|
||||||
|
];
|
||||||
|
|
||||||
|
$csActive = 'qna';
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@extends('web.layouts.subpage')
|
||||||
|
|
||||||
|
@section('title', '1:1 문의 | PIN FOR YOU')
|
||||||
|
@section('meta_description', 'PIN FOR YOU 1:1 문의 페이지입니다. 문의를 남겨주시면 순차적으로 답변드립니다.')
|
||||||
|
@section('canonical', url('/cs/qna'))
|
||||||
|
|
||||||
|
@section('subcontent')
|
||||||
|
<div class="qna-page">
|
||||||
|
@include('web.partials.content-head', [
|
||||||
|
'title' => '문의하기',
|
||||||
|
'desc' => '문의 내용을 남겨주시면 확인 후 빠르게 안내드리겠습니다.'
|
||||||
|
])
|
||||||
|
|
||||||
|
{{-- TODO: 문의 폼 / 내 문의 내역 / 로그인 여부 처리 등 --}}
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
@ -3,7 +3,17 @@
|
|||||||
@section('content')
|
@section('content')
|
||||||
|
|
||||||
{{-- Hero --}}
|
{{-- Hero --}}
|
||||||
@include('web.main.hero-carousel')
|
@php
|
||||||
|
$heroSlides = config('web.hero_slides', []);
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@if(!empty($heroSlides))
|
||||||
|
@include('web.partials.hero-slider', [
|
||||||
|
'slides' => $heroSlides,
|
||||||
|
'variant' => 'main',
|
||||||
|
'id' => 'hero-main'
|
||||||
|
])
|
||||||
|
@endif
|
||||||
|
|
||||||
{{-- Quick Categories --}}
|
{{-- Quick Categories --}}
|
||||||
@include('web.main.quick-categories')
|
@include('web.main.quick-categories')
|
||||||
|
|||||||
@ -4,22 +4,54 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
<title>Voucher Mall - 상품권 최저가 쇼핑</title>
|
{{-- CSRF --}}
|
||||||
|
|
||||||
{{-- SEO --}}
|
|
||||||
<meta name="description" content="상품권, 모바일 교환권, 구글플레이, 문화상품권 등 다양한 모바일 쿠폰 최저가 할인 쇼핑몰">
|
|
||||||
<link rel="canonical" href="{{ rtrim(config('app.url'), '/') }}/">
|
|
||||||
|
|
||||||
{{-- CSRF (추후 폼/로그인 대비) --}}
|
|
||||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||||
|
|
||||||
{{-- Pretendard Font --}}
|
{{-- Canonical/Title/Description (중복 금지) --}}
|
||||||
<link rel="stylesheet" href="{{ asset('css/pretendard.css') }}">
|
@php
|
||||||
<link rel="preload" href="{{ asset('assets/fonts/pretendard/PretendardVariable.woff2') }}" as="font" type="font/woff2" crossorigin>
|
$defaultTitle = 'PIN FOR YOU';
|
||||||
|
$defaultDesc = '상품권, 모바일 교환권, 구글플레이, 문화상품권 등 다양한 모바일 쿠폰을 안전하고 빠르게 할인 구매하세요.';
|
||||||
|
$canonicalUrl = trim($__env->yieldContent('canonical', url()->current()));
|
||||||
|
@endphp
|
||||||
|
|
||||||
{{-- ✅ WEB 전용 번들 로딩 --}}
|
<title>@yield('title', $defaultTitle)</title>
|
||||||
|
<meta name="description" content="@yield('meta_description', $defaultDesc)">
|
||||||
|
<meta name="robots" content="@yield('robots', 'index,follow')">
|
||||||
|
<link rel="canonical" href="{{ $canonicalUrl }}">
|
||||||
|
|
||||||
|
{{-- Open Graph --}}
|
||||||
|
<meta property="og:site_name" content="PIN FOR YOU">
|
||||||
|
<meta property="og:title" content="@yield('og_title', trim($__env->yieldContent('title', $defaultTitle)))">
|
||||||
|
<meta property="og:description" content="@yield('og_description', trim($__env->yieldContent('meta_description', $defaultDesc)))">
|
||||||
|
<meta property="og:url" content="@yield('og_url', $canonicalUrl)">
|
||||||
|
<meta property="og:type" content="@yield('og_type', 'website')">
|
||||||
|
<meta property="og:locale" content="ko_KR">
|
||||||
|
{{-- 대표 이미지 준비되면 사용 (없으면 생략 가능)
|
||||||
|
<meta property="og:image" content="@yield('og_image', asset('assets/images/common/og-default.png'))">
|
||||||
|
--}}
|
||||||
|
|
||||||
|
{{-- Twitter Card (선택이지만 권장) --}}
|
||||||
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
|
<meta name="twitter:title" content="@yield('tw_title', trim($__env->yieldContent('title', $defaultTitle)))">
|
||||||
|
<meta name="twitter:description" content="@yield('tw_description', trim($__env->yieldContent('meta_description', $defaultDesc)))">
|
||||||
|
{{-- <meta name="twitter:image" content="@yield('tw_image', asset('assets/images/common/og-default.png'))"> --}}
|
||||||
|
|
||||||
|
{{-- (선택) 기본 키워드는 큰 의미 없어서 생략 권장 --}}
|
||||||
|
{{-- <meta name="keywords" content="..."> --}}
|
||||||
|
|
||||||
|
{{-- Font --}}
|
||||||
|
<link rel="stylesheet" href="{{ asset('css/pretendard.css') }}">
|
||||||
|
<link rel="preload"
|
||||||
|
href="{{ asset('assets/fonts/pretendard/PretendardVariable.woff2') }}"
|
||||||
|
as="font" type="font/woff2" crossorigin>
|
||||||
|
|
||||||
|
{{-- Web Bundle --}}
|
||||||
@vite(['resources/css/web.css', 'resources/js/web.js'])
|
@vite(['resources/css/web.css', 'resources/js/web.js'])
|
||||||
|
|
||||||
|
{{-- 페이지별 추가 head --}}
|
||||||
|
@yield('head')
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
{{-- Header --}}
|
{{-- Header --}}
|
||||||
|
|||||||
143
resources/views/web/layouts/subpage.blade.php
Normal file
143
resources/views/web/layouts/subpage.blade.php
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
@extends('web.layouts.layout')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="subpage-wrap">
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
{{-- Breadcrumb (optional) --}}
|
||||||
|
@isset($breadcrumbs)
|
||||||
|
@include('web.partials.breadcrumb', ['items' => $breadcrumbs])
|
||||||
|
@endisset
|
||||||
|
|
||||||
|
@php
|
||||||
|
$heroSlides = config('web.hero_slides', []);
|
||||||
|
|
||||||
|
// ✅ 섹션 감지
|
||||||
|
$isCsPage = request()->is('cs') || request()->is('cs/*') || request()->routeIs('web.cs.*');
|
||||||
|
$isMypagePage = request()->is('mypage') || request()->is('mypage/*') || request()->routeIs('web.mypage.*');
|
||||||
|
$isPolicyPage = request()->is('policy') || request()->is('policy/*') || request()->routeIs('web.policy.*');
|
||||||
|
|
||||||
|
// ✅ CS subnav 자동 주입
|
||||||
|
if ($isCsPage && empty($subnavItems)) {
|
||||||
|
$subnavItems = collect(config('web.cs_tabs', []))
|
||||||
|
->map(function ($t) {
|
||||||
|
$url = '#';
|
||||||
|
if (!empty($t['route']) && \Illuminate\Support\Facades\Route::has($t['route'])) {
|
||||||
|
$url = route($t['route']);
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'label' => $t['label'] ?? '',
|
||||||
|
'url' => $url,
|
||||||
|
'key' => $t['key'] ?? null,
|
||||||
|
];
|
||||||
|
})
|
||||||
|
->values()
|
||||||
|
->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ MYPAGE subnav 자동 주입
|
||||||
|
if ($isMypagePage && empty($subnavItems)) {
|
||||||
|
$subnavItems = collect(config('web.mypage_tabs', []))
|
||||||
|
->map(function ($t) {
|
||||||
|
$url = '#';
|
||||||
|
if (!empty($t['route']) && \Illuminate\Support\Facades\Route::has($t['route'])) {
|
||||||
|
$url = route($t['route']);
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'label' => $t['label'] ?? '',
|
||||||
|
'url' => $url,
|
||||||
|
'key' => $t['key'] ?? null,
|
||||||
|
];
|
||||||
|
})
|
||||||
|
->values()
|
||||||
|
->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ PolicyPage subnav 자동 주입
|
||||||
|
if ($isPolicyPage && empty($subnavItems)) {
|
||||||
|
$subnavItems = collect(config('web.policy_tabs', []))
|
||||||
|
->map(function ($t) {
|
||||||
|
$url = '#';
|
||||||
|
if (!empty($t['route']) && \Illuminate\Support\Facades\Route::has($t['route'])) {
|
||||||
|
$url = route($t['route']);
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'label' => $t['label'] ?? '',
|
||||||
|
'url' => $url,
|
||||||
|
'key' => $t['key'] ?? null,
|
||||||
|
];
|
||||||
|
})
|
||||||
|
->values()
|
||||||
|
->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ active key 우선순위: 각 섹션 전용 변수 -> 기존 subnavActive
|
||||||
|
$subnavActive = $csActive ?? $mypageActive ?? ($subnavActive ?? null);
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@if(!empty($heroSlides))
|
||||||
|
@include('web.partials.hero-slider', [
|
||||||
|
'slides' => $heroSlides,
|
||||||
|
'variant' => 'compact',
|
||||||
|
'id' => 'hero-sub'
|
||||||
|
])
|
||||||
|
@endif
|
||||||
|
|
||||||
|
{{-- Header --}}
|
||||||
|
@include('web.partials.subpage-header', [
|
||||||
|
'title' => $pageTitle ?? '페이지 제목',
|
||||||
|
'desc' => $pageDesc ?? null
|
||||||
|
])
|
||||||
|
|
||||||
|
{{-- Body --}}
|
||||||
|
<div class="subpage-grid">
|
||||||
|
|
||||||
|
{{-- ✅ 고객센터면 cs-tabs --}}
|
||||||
|
@if($isCsPage)
|
||||||
|
@include('web.partials.cs-tabs', [
|
||||||
|
'activeKey' => $subnavActive
|
||||||
|
])
|
||||||
|
|
||||||
|
{{-- ✅ 마이페이지면 mypage-tabs --}}
|
||||||
|
@elseif($isMypagePage)
|
||||||
|
@include('web.partials.mypage-tabs', [
|
||||||
|
'activeKey' => $subnavActive
|
||||||
|
])
|
||||||
|
|
||||||
|
@elseif($isPolicyPage)
|
||||||
|
@include('web.partials.policy-tabs', [
|
||||||
|
'activeKey' => $subnavActive
|
||||||
|
])
|
||||||
|
|
||||||
|
{{-- 그 외 일반 서브페이지는 기존 방식 유지 --}}
|
||||||
|
@else
|
||||||
|
{{-- Mobile Tabs --}}
|
||||||
|
<div class="subpage-tabs">
|
||||||
|
@include('web.partials.subpage-sidenav', [
|
||||||
|
'items' => $subnavItems ?? [],
|
||||||
|
'active' => $subnavActive ?? null,
|
||||||
|
'mode' => 'tabs'
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Desktop Side --}}
|
||||||
|
<aside class="subpage-side" aria-label="서브메뉴">
|
||||||
|
@include('web.partials.subpage-sidenav', [
|
||||||
|
'items' => $subnavItems ?? [],
|
||||||
|
'active' => $subnavActive ?? null,
|
||||||
|
'mode' => 'side'
|
||||||
|
])
|
||||||
|
</aside>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
{{-- Main --}}
|
||||||
|
<main class="subpage-main" id="main-content">
|
||||||
|
<div class="content-card">
|
||||||
|
@yield('subcontent')
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
@ -1,52 +0,0 @@
|
|||||||
<section class="hero-slider" aria-label="프로모션 배너">
|
|
||||||
<div class="hero-track">
|
|
||||||
<!-- Slide 1 -->
|
|
||||||
<div class="hero-slide" style="background: linear-gradient(135deg, #EFF6FF 0%, #FFFFFF 100%);">
|
|
||||||
<div class="container hero-content">
|
|
||||||
<span style="color: var(--color-accent-blue); font-weight: 700; margin-bottom: 8px; display: block;">특별
|
|
||||||
프로모션</span>
|
|
||||||
<h1 class="hero-title">구글플레이 기프트카드<br>최대 12% 즉시 할인</h1>
|
|
||||||
<p class="hero-desc">인기 게임 아이템부터 영화까지, 더 저렴하게 즐기세요.</p>
|
|
||||||
<a href="/shop?category=google" class="btn btn-primary">지금 구매하기</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Slide 2 -->
|
|
||||||
<div class="hero-slide" style="background: linear-gradient(135deg, #F0FDFA 0%, #FFFFFF 100%);">
|
|
||||||
<div class="container hero-content">
|
|
||||||
<span style="color: #059669; font-weight: 700; margin-bottom: 8px; display: block;">신규 입점</span>
|
|
||||||
<h1 class="hero-title">문화상품권 24시간<br>자동 발송 시스템 오픈</h1>
|
|
||||||
<p class="hero-desc">기다림 없이 결제 즉시 문자로 핀번호를 받아보세요.</p>
|
|
||||||
<a href="/shop?category=paper" class="btn btn-primary" style="background-color: #059669;">상품 보러가기</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Slide 3 -->
|
|
||||||
<div class="hero-slide" style="background: linear-gradient(135deg, #FFF7ED 0%, #FFFFFF 100%);">
|
|
||||||
<div class="container hero-content">
|
|
||||||
<span style="color: #EA580C; font-weight: 700; margin-bottom: 8px; display: block;">한정 수량</span>
|
|
||||||
<h1 class="hero-title">편의점 모바일 금액권<br>5만원권 10% 핫딜</h1>
|
|
||||||
<p class="hero-desc">CU, GS25, 세븐일레븐 전국 어디서나 사용 가능</p>
|
|
||||||
<a href="/shop?category=convenience" class="btn btn-primary" style="background-color: #EA580C;">구매하기</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button class="slider-arrow prev" aria-label="이전 슬라이드"
|
|
||||||
style="position: absolute; left: 24px; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; border-radius: 50%; background: white; box-shadow: var(--shadow-md); display: flex; align-items: center; justify-content: center;">
|
|
||||||
<svg width="24" height="24" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<button class="slider-arrow next" aria-label="다음 슬라이드"
|
|
||||||
style="position: absolute; right: 24px; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; border-radius: 50%; background: white; box-shadow: var(--shadow-md); display: flex; align-items: center; justify-content: center;">
|
|
||||||
<svg width="24" height="24" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="dots-container">
|
|
||||||
<!-- Script will populate docs based on slide count -->
|
|
||||||
<div class="dot active"></div>
|
|
||||||
<div class="dot"></div>
|
|
||||||
<div class="dot"></div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
33
resources/views/web/partials/breadcrumb.blade.php
Normal file
33
resources/views/web/partials/breadcrumb.blade.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
@props(['items' => []])
|
||||||
|
|
||||||
|
<nav class="breadcrumb" aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb-list">
|
||||||
|
@foreach($items as $i => $it)
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
@if(!empty($it['url']) && $i < count($items)-1)
|
||||||
|
<a href="{{ $it['url'] }}" class="breadcrumb-link">{{ $it['label'] }}</a>
|
||||||
|
@else
|
||||||
|
<span class="breadcrumb-current" aria-current="page">{{ $it['label'] }}</span>
|
||||||
|
@endif
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{{-- SEO: Breadcrumb JSON-LD --}}
|
||||||
|
@php
|
||||||
|
$ld = [
|
||||||
|
"@context" => "https://schema.org",
|
||||||
|
"@type" => "BreadcrumbList",
|
||||||
|
"itemListElement" => []
|
||||||
|
];
|
||||||
|
foreach($items as $idx => $it){
|
||||||
|
$ld["itemListElement"][] = [
|
||||||
|
"@type" => "ListItem",
|
||||||
|
"position" => $idx+1,
|
||||||
|
"name" => $it["label"],
|
||||||
|
"item" => $it["url"] ?? url()->current()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
|
<script type="application/ld+json">{!! json_encode($ld, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES) !!}</script>
|
||||||
8
resources/views/web/partials/content-head.blade.php
Normal file
8
resources/views/web/partials/content-head.blade.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
@props(['title' => '', 'desc' => null])
|
||||||
|
|
||||||
|
<div class="list-head">
|
||||||
|
<h2 class="list-title">{{ $title }}</h2>
|
||||||
|
@if($desc)
|
||||||
|
<p class="list-desc">{{ $desc }}</p>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
44
resources/views/web/partials/cs-tabs.blade.php
Normal file
44
resources/views/web/partials/cs-tabs.blade.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
@php
|
||||||
|
// config에서 CS 탭 가져와서, 기존 subpage-sidenav가 기대하는 형식(label,url,key)으로 변환
|
||||||
|
$items = collect(config('web.cs_tabs', []))
|
||||||
|
->map(function ($t) {
|
||||||
|
return [
|
||||||
|
'label' => $t['label'] ?? '',
|
||||||
|
'url' => isset($t['route']) ? route($t['route']) : '#',
|
||||||
|
'key' => $t['key'] ?? null,
|
||||||
|
];
|
||||||
|
})
|
||||||
|
->values()
|
||||||
|
->all();
|
||||||
|
|
||||||
|
// activeKey는 페이지에서 넘기거나, 없으면 현재 route로 자동 판별도 가능
|
||||||
|
$activeKey = $activeKey ?? null;
|
||||||
|
|
||||||
|
if (!$activeKey) {
|
||||||
|
// route 기반 자동 active (routeIs가 동작하려면 routes에 name이 있어야 함)
|
||||||
|
foreach (config('web.cs_tabs', []) as $t) {
|
||||||
|
if (!empty($t['route']) && request()->routeIs($t['route'])) {
|
||||||
|
$activeKey = $t['key'] ?? null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
{{-- Mobile Tabs --}}
|
||||||
|
<div class="subpage-tabs">
|
||||||
|
@include('web.partials.subpage-sidenav', [
|
||||||
|
'items' => $items,
|
||||||
|
'active' => $activeKey,
|
||||||
|
'mode' => 'tabs'
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Desktop Side --}}
|
||||||
|
<aside class="subpage-side" aria-label="고객센터 메뉴">
|
||||||
|
@include('web.partials.subpage-sidenav', [
|
||||||
|
'items' => $items,
|
||||||
|
'active' => $activeKey,
|
||||||
|
'mode' => 'side'
|
||||||
|
])
|
||||||
|
</aside>
|
||||||
43
resources/views/web/partials/hero-slider.blade.php
Normal file
43
resources/views/web/partials/hero-slider.blade.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
@props([
|
||||||
|
'slides' => [],
|
||||||
|
'variant' => 'main', // 'main' | 'compact'
|
||||||
|
'id' => 'hero'
|
||||||
|
])
|
||||||
|
@if(!empty($slides))
|
||||||
|
<section class="hero-slider hero-slider--{{ $variant }}" id="{{ $id }}" aria-label="프로모션 배너">
|
||||||
|
<div class="hero-track">
|
||||||
|
@foreach($slides as $s)
|
||||||
|
<div class="hero-slide">
|
||||||
|
<div class="hero-content">
|
||||||
|
@if(!empty($s['kicker']))
|
||||||
|
<div class="hero-kicker">{{ $s['kicker'] }}</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<h2 class="hero-title">{{ $s['title'] }}</h2>
|
||||||
|
|
||||||
|
@if(!empty($s['desc']))
|
||||||
|
<p class="hero-desc">{{ $s['desc'] }}</p>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if(!empty($s['cta_label']) && !empty($s['cta_url']))
|
||||||
|
<a href="{{ $s['cta_url'] }}" class="btn btn-primary hero-cta">
|
||||||
|
{{ $s['cta_label'] }}
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if(count($slides) > 1)
|
||||||
|
<button class="slider-arrow prev" aria-label="이전 배너">‹</button>
|
||||||
|
<button class="slider-arrow next" aria-label="다음 배너">›</button>
|
||||||
|
|
||||||
|
<div class="dots-container" aria-label="배너 선택">
|
||||||
|
@foreach($slides as $idx => $s)
|
||||||
|
<button class="dot {{ $idx===0?'active':'' }}" data-index="{{ $idx }}" aria-label="배너 {{ $idx+1 }}"></button>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</section>
|
||||||
|
@endif
|
||||||
45
resources/views/web/partials/mypage-tabs.blade.php
Normal file
45
resources/views/web/partials/mypage-tabs.blade.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
@php
|
||||||
|
$rawTabs = config('web.mypage_tabs', []);
|
||||||
|
|
||||||
|
$items = collect($rawTabs)->map(function ($t) {
|
||||||
|
$url = '#';
|
||||||
|
if (!empty($t['route']) && \Illuminate\Support\Facades\Route::has($t['route'])) {
|
||||||
|
$url = route($t['route']);
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'label' => $t['label'] ?? '',
|
||||||
|
'url' => $url,
|
||||||
|
'key' => $t['key'] ?? null,
|
||||||
|
];
|
||||||
|
})->values()->all();
|
||||||
|
|
||||||
|
$activeKey = $activeKey ?? null;
|
||||||
|
|
||||||
|
// activeKey가 없으면 현재 라우트로 자동 판별
|
||||||
|
if (!$activeKey) {
|
||||||
|
foreach ($rawTabs as $t) {
|
||||||
|
if (!empty($t['route']) && request()->routeIs($t['route'])) {
|
||||||
|
$activeKey = $t['key'] ?? null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
{{-- Mobile Tabs --}}
|
||||||
|
<div class="subpage-tabs">
|
||||||
|
@include('web.partials.subpage-sidenav', [
|
||||||
|
'items' => $items,
|
||||||
|
'active' => $activeKey,
|
||||||
|
'mode' => 'tabs'
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Desktop Side --}}
|
||||||
|
<aside class="subpage-side" aria-label="마이페이지 메뉴">
|
||||||
|
@include('web.partials.subpage-sidenav', [
|
||||||
|
'items' => $items,
|
||||||
|
'active' => $activeKey,
|
||||||
|
'mode' => 'side'
|
||||||
|
])
|
||||||
|
</aside>
|
||||||
44
resources/views/web/partials/policy-tabs.blade.php
Normal file
44
resources/views/web/partials/policy-tabs.blade.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
@php
|
||||||
|
$rawTabs = config('web.policy_tabs', []);
|
||||||
|
|
||||||
|
$items = collect($rawTabs)->map(function ($t) {
|
||||||
|
$url = '#';
|
||||||
|
if (!empty($t['route']) && \Illuminate\Support\Facades\Route::has($t['route'])) {
|
||||||
|
$url = route($t['route']);
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'label' => $t['label'] ?? '',
|
||||||
|
'url' => $url,
|
||||||
|
'key' => $t['key'] ?? null,
|
||||||
|
];
|
||||||
|
})->values()->all();
|
||||||
|
|
||||||
|
$activeKey = $activeKey ?? null;
|
||||||
|
|
||||||
|
if (!$activeKey) {
|
||||||
|
foreach ($rawTabs as $t) {
|
||||||
|
if (!empty($t['route']) && request()->routeIs($t['route'])) {
|
||||||
|
$activeKey = $t['key'] ?? null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
{{-- Mobile Tabs --}}
|
||||||
|
<div class="subpage-tabs">
|
||||||
|
@include('web.partials.subpage-sidenav', [
|
||||||
|
'items' => $items,
|
||||||
|
'active' => $activeKey,
|
||||||
|
'mode' => 'tabs'
|
||||||
|
])
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Desktop Side --}}
|
||||||
|
<aside class="subpage-side" aria-label="약관 및 정책 메뉴">
|
||||||
|
@include('web.partials.subpage-sidenav', [
|
||||||
|
'items' => $items,
|
||||||
|
'active' => $activeKey,
|
||||||
|
'mode' => 'side'
|
||||||
|
])
|
||||||
|
</aside>
|
||||||
4
resources/views/web/partials/subpage-header.blade.php
Normal file
4
resources/views/web/partials/subpage-header.blade.php
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<header class="subpage-header">
|
||||||
|
<h1 class="subpage-title">{{ $title }}</h1>
|
||||||
|
@if($desc) <p class="subpage-desc">{{ $desc }}</p> @endif
|
||||||
|
</header>
|
||||||
29
resources/views/web/partials/subpage-sidenav.blade.php
Normal file
29
resources/views/web/partials/subpage-sidenav.blade.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@props(['items' => [], 'active' => null, 'mode' => 'side'])
|
||||||
|
|
||||||
|
@if($mode === 'tabs')
|
||||||
|
<nav class="subnav subnav--tabs" aria-label="서브메뉴 탭">
|
||||||
|
@foreach($items as $it)
|
||||||
|
@php $isActive = ($active && $active === ($it['key'] ?? $it['url'])); @endphp
|
||||||
|
<a href="{{ $it['url'] }}"
|
||||||
|
class="subnav-tab {{ $isActive ? 'is-active' : '' }}"
|
||||||
|
@if($isActive) aria-current="page" @endif>
|
||||||
|
{{ $it['label'] }}
|
||||||
|
</a>
|
||||||
|
@endforeach
|
||||||
|
</nav>
|
||||||
|
@else
|
||||||
|
<nav class="subnav subnav--side" aria-label="서브메뉴">
|
||||||
|
<ul class="subnav-list">
|
||||||
|
@foreach($items as $it)
|
||||||
|
@php $isActive = ($active && $active === ($it['key'] ?? $it['url'])); @endphp
|
||||||
|
<li>
|
||||||
|
<a href="{{ $it['url'] }}"
|
||||||
|
class="subnav-link {{ $isActive ? 'is-active' : '' }}"
|
||||||
|
@if($isActive) aria-current="page" @endif>
|
||||||
|
{{ $it['label'] }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
@endif
|
||||||
29
resources/views/web/policy/email/index.blade.php
Normal file
29
resources/views/web/policy/email/index.blade.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@php
|
||||||
|
$pageTitle = '이메일무단수집거부';
|
||||||
|
$pageDesc = '웹사이트 내 이메일 주소의 무단 수집을 거부합니다.';
|
||||||
|
|
||||||
|
$breadcrumbs = [
|
||||||
|
['label' => '홈', 'url' => url('/')],
|
||||||
|
['label' => '약관 및 정책', 'url' => url('/policy')],
|
||||||
|
['label' => '이메일무단수집거부', 'url' => url()->current()],
|
||||||
|
];
|
||||||
|
|
||||||
|
$policyActive = 'email';
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@extends('web.layouts.subpage')
|
||||||
|
|
||||||
|
@section('title', '이메일무단수집거부 | PIN FOR YOU')
|
||||||
|
@section('meta_description', 'PIN FOR YOU 이메일무단수집거부 안내입니다. 무단 수집 및 이용에 대한 조치를 안내합니다.')
|
||||||
|
@section('canonical', url('/policy/email'))
|
||||||
|
|
||||||
|
@section('subcontent')
|
||||||
|
<div class="policy-email-page">
|
||||||
|
@include('web.partials.content-head', [
|
||||||
|
'title' => '무단 수집 금지 안내',
|
||||||
|
'desc' => '자동 수집 프로그램 등을 통한 이메일 주소 수집을 금지합니다.'
|
||||||
|
])
|
||||||
|
|
||||||
|
{{-- TODO: 이메일무단수집거부 본문 --}}
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
29
resources/views/web/policy/index.blade.php
Normal file
29
resources/views/web/policy/index.blade.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@php
|
||||||
|
$pageTitle = '이용약관';
|
||||||
|
$pageDesc = '서비스 이용 조건, 책임 범위, 분쟁 처리 기준 안내.';
|
||||||
|
|
||||||
|
$breadcrumbs = [
|
||||||
|
['label' => '홈', 'url' => url('/')],
|
||||||
|
['label' => '약관 및 정책', 'url' => url('/policy')],
|
||||||
|
['label' => '이용약관', 'url' => url()->current()],
|
||||||
|
];
|
||||||
|
|
||||||
|
$policyActive = 'terms';
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@extends('web.layouts.subpage')
|
||||||
|
|
||||||
|
@section('title', '이용약관 | PIN FOR YOU')
|
||||||
|
@section('meta_description', 'PIN FOR YOU 이용약관입니다. 서비스 이용 조건과 책임 범위, 분쟁 처리 기준을 안내합니다.')
|
||||||
|
@section('canonical', url('/policy/terms'))
|
||||||
|
|
||||||
|
@section('subcontent')
|
||||||
|
<div class="policy-terms-page">
|
||||||
|
@include('web.partials.content-head', [
|
||||||
|
'title' => '서비스 이용 규칙',
|
||||||
|
'desc' => '회원 의무, 거래/결제, 환불, 제재 기준을 포함합니다.'
|
||||||
|
])
|
||||||
|
|
||||||
|
{{-- TODO: 이용약관 본문 --}}
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
29
resources/views/web/policy/privacy/index.blade.php
Normal file
29
resources/views/web/policy/privacy/index.blade.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@php
|
||||||
|
$pageTitle = '개인정보처리방침';
|
||||||
|
$pageDesc = '개인정보 수집/이용/보관/파기 및 이용자 권리 안내.';
|
||||||
|
|
||||||
|
$breadcrumbs = [
|
||||||
|
['label' => '홈', 'url' => url('/')],
|
||||||
|
['label' => '약관 및 정책', 'url' => url('/policy')],
|
||||||
|
['label' => '개인정보처리방침', 'url' => url()->current()],
|
||||||
|
];
|
||||||
|
|
||||||
|
$policyActive = 'privacy';
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@extends('web.layouts.subpage')
|
||||||
|
|
||||||
|
@section('title', '개인정보처리방침 | PIN FOR YOU')
|
||||||
|
@section('meta_description', 'PIN FOR YOU 개인정보처리방침입니다. 개인정보 수집/이용/보관/파기 및 이용자 권리를 안내합니다.')
|
||||||
|
@section('canonical', url('/policy/privacy'))
|
||||||
|
|
||||||
|
@section('subcontent')
|
||||||
|
<div class="policy-privacy-page">
|
||||||
|
@include('web.partials.content-head', [
|
||||||
|
'title' => '개인정보 처리 기준',
|
||||||
|
'desc' => '수집 목적, 보관 기간, 제공/위탁, 이용자 권리 내용을 포함합니다.'
|
||||||
|
])
|
||||||
|
|
||||||
|
{{-- TODO: 개인정보처리방침 본문 --}}
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
29
resources/views/web/policy/terms/index.blade.php
Normal file
29
resources/views/web/policy/terms/index.blade.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@php
|
||||||
|
$pageTitle = '개인정보처리방침';
|
||||||
|
$pageDesc = '개인정보 수집/이용/보관/파기 및 이용자 권리 안내.';
|
||||||
|
|
||||||
|
$breadcrumbs = [
|
||||||
|
['label' => '홈', 'url' => url('/')],
|
||||||
|
['label' => '약관 및 정책', 'url' => url('/policy')],
|
||||||
|
['label' => '개인정보처리방침', 'url' => url()->current()],
|
||||||
|
];
|
||||||
|
|
||||||
|
$policyActive = 'privacy';
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@extends('web.layouts.subpage')
|
||||||
|
|
||||||
|
@section('title', '개인정보처리방침 | PIN FOR YOU')
|
||||||
|
@section('meta_description', 'PIN FOR YOU 개인정보처리방침입니다. 개인정보 수집/이용/보관/파기 및 이용자 권리를 안내합니다.')
|
||||||
|
@section('canonical', url('/policy/privacy'))
|
||||||
|
|
||||||
|
@section('subcontent')
|
||||||
|
<div class="policy-privacy-page">
|
||||||
|
@include('web.partials.content-head', [
|
||||||
|
'title' => '개인정보 처리 기준',
|
||||||
|
'desc' => '수집 목적, 보관 기간, 제공/위탁, 이용자 권리 내용을 포함합니다.'
|
||||||
|
])
|
||||||
|
|
||||||
|
{{-- TODO: 개인정보처리방침 본문 --}}
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
@ -7,4 +7,26 @@ Route::get('/', function () {
|
|||||||
|
|
||||||
Route::view('/', 'web.home')->name('web.home');
|
Route::view('/', 'web.home')->name('web.home');
|
||||||
|
|
||||||
|
Route::prefix('cs')->name('web.cs.')->group(function () {
|
||||||
|
Route::view('/notice', 'web.cs.notice.index')->name('notice.index');
|
||||||
|
Route::view('/faq', 'web.cs.faq.index')->name('faq.index');
|
||||||
|
Route::view('/kakao', 'web.cs.kakao.index')->name('kakao.index');
|
||||||
|
Route::view('/qna', 'web.cs.qna.index')->name('qna.index');
|
||||||
|
Route::view('/guide', 'web.cs.guide.index')->name('guide.index');
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::prefix('mypage')->name('web.mypage.')->group(function () {
|
||||||
|
Route::view('/info', 'web.mypage.info.index')->name('info.index');
|
||||||
|
Route::view('/usage', 'web.mypage.usage.index')->name('usage.index');
|
||||||
|
Route::view('/exchange', 'web.mypage.exchange.index')->name('exchange.index');
|
||||||
|
Route::view('/qna', 'web.mypage.qna.index')->name('qna.index');
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::prefix('policy')->name('web.policy.')->group(function () {
|
||||||
|
Route::view('/', 'web.policy.index')->name('index');
|
||||||
|
Route::view('/privacy', 'web.policy.privacy.index')->name('privacy.index');
|
||||||
|
Route::view('/terms', 'web.policy.terms.index')->name('terms.index');
|
||||||
|
Route::view('/email', 'web.policy.email.index')->name('email.index');
|
||||||
|
});
|
||||||
|
|
||||||
Route::fallback(fn () => abort(404));
|
Route::fallback(fn () => abort(404));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user