Files
sam-manage/resources/views/components/sidebar/menu-item.blade.php
김보곤 efd8d96156 feat: [sidebar] 사이드바 메뉴 즐겨찾기 기능 추가
- MenuFavorite 모델 생성 (menu_favorites 테이블)
- SidebarMenuService에 즐겨찾기 CRUD 메서드 추가
- MenuFavoriteController 생성 (toggle/reorder API)
- 사이드바 상단에 즐겨찾기 섹션 표시
- 메뉴 아이템에 별 아이콘 추가 (hover 시 표시, 토글)
- 최대 10개 제한, 리프 메뉴만 대상
2026-03-06 14:34:27 +09:00

80 lines
3.3 KiB
PHP

@props(['menu', 'depth' => 0])
@php
$sidebarMenuService = app(\App\Services\SidebarMenuService::class);
$isActive = $sidebarMenuService->isMenuActive($menu);
$paddingLeft = $depth > 0 ? ($depth * 0.75 + 0.75) . 'rem' : '0.75rem';
$url = $menu->url;
if ($menu->is_external && $menu->external_url) {
$url = $menu->external_url;
}
// 라우트명이 있으면 라우트 URL 사용
$routeName = $menu->getRouteName();
if ($routeName && !str_contains($routeName, '*') && \Route::has($routeName)) {
$url = route($routeName);
}
$activeClass = $isActive
? 'bg-primary text-white hover:bg-primary'
: 'text-gray-700 hover:bg-gray-100';
$target = $menu->is_external ? '_blank' : '_self';
// 즐겨찾기 여부
$isFavorited = isset($favoriteMenuIds) && in_array($menu->id, $favoriteMenuIds);
// 메뉴 뱃지 확인 (라우트명 또는 URL 기준)
$badgeCount = 0;
$badgeColor = '#ef4444';
if (isset($menuBadges)) {
$badge = null;
// 라우트명으로 찾기
if ($routeName && isset($menuBadges['byRoute'][$routeName])) {
$badge = $menuBadges['byRoute'][$routeName];
}
// URL로 찾기
elseif ($menu->url && isset($menuBadges['byUrl'][$menu->url])) {
$badge = $menuBadges['byUrl'][$menu->url];
}
if ($badge) {
$badgeCount = is_array($badge) ? ($badge['count'] ?? 0) : $badge;
$badgeColor = is_array($badge) ? ($badge['color'] ?? '#ef4444') : '#ef4444';
}
}
@endphp
<li class="group">
<a href="{{ $url }}"
class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm {{ $activeClass }}"
style="padding-left: {{ $paddingLeft }}"
title="{{ $menu->name }}"
@if($menu->is_external) target="{{ $target }}" rel="noopener noreferrer" hx-boost="false" @endif
>
@if($menu->icon)
<x-sidebar.menu-icon :icon="$menu->icon" />
@endif
<span class="sidebar-text flex-1">{{ $menu->name }}</span>
@if($badgeCount > 0)
<span class="sidebar-text inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1.5 text-xs font-bold text-white rounded-full"
style="background-color: {{ $badgeColor }};">
{{ $badgeCount > 99 ? '99+' : $badgeCount }}
</span>
@endif
@if($menu->is_external)
<x-sidebar.menu-icon icon="external-link" class="w-3 h-3 opacity-50" />
@endif
{{-- 즐겨찾기 아이콘 --}}
<button type="button"
onclick="event.preventDefault(); event.stopPropagation(); toggleMenuFavorite({{ $menu->id }}, this)"
class="sidebar-text fav-star shrink-0 p-0.5 rounded transition-all {{ $isFavorited ? 'text-yellow-400 fav-active' : 'text-gray-300 opacity-0 group-hover:opacity-100' }}"
title="{{ $isFavorited ? '즐겨찾기 해제' : '즐겨찾기 추가' }}"
data-menu-id="{{ $menu->id }}">
<svg class="w-3.5 h-3.5" fill="{{ $isFavorited ? 'currentColor' : 'none' }}" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
</svg>
</button>
</a>
</li>