giftcon_dev/resources/views/web/partials/subpage-sidenav.blade.php
2026-03-03 15:13:16 +09:00

192 lines
7.2 KiB
PHP

@php
$items = $items ?? [];
$active = $active ?? null;
$mode = $mode ?? 'side';
$isShop = $isShop ?? false;
$title = $title ?? null;
// 현재 활성화된 아이템 찾기
$activeItem = collect($items)->first(function($it) use ($active, $isShop) {
if($isShop) return $active == $it['id'];
return $active === ($it['key'] ?? $it['url']);
});
if (!$activeItem && $isShop) {
foreach($items as $it) {
if(!empty($it['children'])) {
$child = collect($it['children'])->firstWhere('id', $active);
if($child) { $activeItem = $child; break; }
}
}
}
@endphp
@if($mode === 'tabs')
{{-- 모바일 전용: 줄에 2개씩 배치되는 그리드 디자인 --}}
<nav class="mobile-subnav-grid" aria-label="모바일 카테고리">
<div class="m-grid-container">
@foreach($items as $it)
@php
$isActive = $isShop ? ($active == $it['id']) : ($active && $active === ($it['key'] ?? $it['url']));
$hasActiveChild = $isShop && !empty($it['children']) && collect($it['children'])->contains('id', $active);
$isOpen = $isActive || $hasActiveChild;
@endphp
<div class="m-grid-item {{ $isOpen ? 'is-open' : '' }}">
<a href="{{ $it['url'] ?? '#' }}"
class="m-grid-link {{ $isOpen ? 'is-active' : '' }}">
{{ $it['label'] ?? '' }}
</a>
{{-- 1 메뉴 활성 2 메뉴 노출 (그리드 아래로 펼쳐짐) --}}
@if($isShop && !empty($it['children']) && $isOpen)
<div class="m-grid-sub-wrap">
@foreach($it['children'] as $child)
<a href="{{ $child['url'] }}"
class="m-grid-sub-link {{ $active == $child['id'] ? 'is-active' : '' }}">
{{ $child['label'] }}
</a>
@endforeach
</div>
@endif
</div>
@endforeach
</div>
</nav>
@else
{{-- 데스크톱 전용: 프리미엄 사이드바 (기존 유지) --}}
<nav class="subnav subnav--side">
<div class="subnav-box premium-design">
@if($title)
<div class="subnav-head">
<div class="subnav-title">{{ $title }}</div>
<div class="subnav-accent"></div>
</div>
@endif
<ul class="subnav-list">
@foreach($items as $it)
@php
$isActive = $isShop ? ($active == $it['id']) : ($active && $active === ($it['key'] ?? $it['url']));
$hasActiveChild = $isShop && !empty($it['children']) && collect($it['children'])->contains('id', $active);
@endphp
<li class="nav-group {{ $isActive || $hasActiveChild ? 'is-open' : '' }}">
<a href="{{ $it['url'] ?? '#' }}" class="nav-main-link {{ $isActive ? 'is-active' : '' }}">
<span class="label-text">{{ $it['label'] ?? '' }}</span>
@if(!empty($it['children']))
<i class="bi bi-chevron-down arrow-icon"></i>
@endif
</a>
@if($isShop && !empty($it['children']))
<ul class="nav-sub-list">
@foreach($it['children'] as $child)
<li>
<a href="{{ $child['url'] }}"
class="nav-sub-link {{ $active == $child['id'] ? 'is-active' : '' }}">
{{ $child['label'] }}
</a>
</li>
@endforeach
</ul>
@endif
</li>
@endforeach
</ul>
</div>
</nav>
@endif
<style>
/* --- 모바일 그리드(Grid) 스타일 --- */
.mobile-subnav-grid {
margin-bottom: 25px;
}
.m-grid-container {
display: grid;
grid-template-columns: 1fr 1fr; /* 한 줄에 2개 */
gap: 10px;
}
/* 2차 메뉴가 열릴 때 해당 행 전체를 차지하도록 설정 */
.m-grid-item.is-open {
grid-column: span 2; /* 활성화된 메뉴는 한 줄 전체 차지 (2차 메뉴 가독성) */
}
.m-grid-link {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
background: #f8f9fa;
color: #444;
border-radius: 12px;
font-size: 0.95rem;
font-weight: 600;
text-decoration: none;
border: 1px solid #eee;
transition: all 0.2s;
text-align: center;
}
.m-grid-link.is-active {
background: #007bff;
color: #fff;
border-color: #007bff;
box-shadow: 0 4px 12px rgba(0, 123, 255, 0.2);
}
/* 모바일 2차 메뉴 리스트 */
.m-grid-sub-wrap {
display: grid;
grid-template-columns: 1fr 1fr; /* 2차 메뉴도 2개씩 */
gap: 8px;
background: #f1f3f5;
padding: 12px;
border-radius: 12px;
margin-top: 8px;
}
.m-grid-sub-link {
display: block;
padding: 8px;
font-size: 0.85rem;
color: #666;
text-decoration: none;
background: #fff;
border-radius: 8px;
text-align: center;
border: 1px solid #e9ecef;
}
.m-grid-sub-link.is-active {
color: #007bff;
font-weight: 700;
border-color: #007bff;
}
/* --- 데스크톱 프리미엄 사이드바 (기존 유지) --- */
.premium-design { border: none; background: #fff; box-shadow: 0 4px 20px rgba(0,0,0,0.05); border-radius: 20px; padding: 15px; }
.subnav-head { padding: 10px 15px 15px; }
.subnav-title { font-size: 0.75rem; font-weight: 800; color: #bbb; letter-spacing: 1px; }
.subnav-accent { width: 20px; height: 3px; background: #007bff; margin-top: 6px; border-radius: 2px; }
.nav-main-link {
display: flex; align-items: center; justify-content: space-between;
padding: 12px 16px; color: #444; font-weight: 600; border-radius: 12px; transition: 0.3s; text-decoration: none; margin-bottom: 2px;
}
.nav-main-link:hover { background: #f8f9fa; }
.nav-main-link.is-active { background: #007bff; color: #fff; }
.nav-sub-list { list-style: none; padding: 5px 0 10px 15px; }
.nav-sub-link { display: block; padding: 7px 15px; font-size: 0.85rem; color: #777; text-decoration: none; border-radius: 8px; }
.nav-sub-link.is-active { color: #007bff; background: #f0f7ff; font-weight: 700; }
/* 화면 크기에 따른 노출 제어 */
@media (max-width: 991px) {
.subnav--side { display: none; }
}
@media (min-width: 992px) {
.mobile-subnav-grid { display: none; }
}
</style>