Jelajahi Sumber

관리자 메뉴 정리

DESKTOP-T61HUSC\user 1 bulan lalu
induk
melakukan
14bdd690a9
3 mengubah file dengan 175 tambahan dan 138 penghapusan
  1. 101 29
      app/assets/scss/admin.scss
  2. 74 71
      app/layouts/admin.vue
  3. 0 38
      app/pages/site-manager/dashboard.vue

+ 101 - 29
app/assets/scss/admin.scss

@@ -805,7 +805,6 @@ html {
 
 
 header {
-  width: 100%;
   position: sticky;
   top: 0px;
   z-index: 1000;
@@ -1241,12 +1240,13 @@ footer {
 // Light Theme Color Variables
 :root {
   --admin-yellow: #e8b546;
-  --admin-bg-primary: #f5f5f5;
+  --admin-bg-navy: #1a2332;
+  --admin-bg-primary: rgba(246, 247, 248, 1);
   --admin-bg-secondary: #ffffff;
   --admin-bg-tertiary: #f6f7f8;
   --admin-text-primary: #181d29;
   --admin-text-secondary: #666b75;
-  --admin-text-muted: #999999;
+  --admin-text-muted: #a8adb8;
   --admin-border-color: #e0e0e0;
   --admin-accent-primary: #1A2332;
   --admin-accent-hover: #1A2332;
@@ -1581,7 +1581,6 @@ footer {
 
 // Admin Layout
 .admin--layout {
-  min-height: 100vh;
   background: var(--admin-bg-primary);
   font-family: 'FORDKOREAType', sans-serif;
 }
@@ -1590,7 +1589,7 @@ footer {
 .admin--header {
   position: fixed;
   top: 0;
-  left: 0;
+  left: 240px;
   right: 0;
   height: 64px;
   background: var(--admin-bg-secondary);
@@ -1612,11 +1611,10 @@ footer {
     gap: 12px;
 
     h1 {
-      font-size: 28px;
+      font-size: 18px;
       font-weight: 700;
       color: var(--admin-text-primary);
       margin: 0;
-      letter-spacing: 2px;
     }
 
     .admin--logo-sub {
@@ -1663,7 +1661,7 @@ footer {
 }
 
 // Admin Content Wrapper
-.admin--content-wrapper {
+.admin--content--wrapper {
   display: flex;
   margin-top: 64px;
   min-height: calc(100vh - 64px);
@@ -1671,15 +1669,42 @@ footer {
 
 // Admin Sidebar
 .admin--sidebar {
-  width: 260px;
-  background: var(--admin-bg-secondary);
-  border-right: 1px solid var(--admin-border-color);
-  padding: 24px 0;
+  width: 240px;
   position: fixed;
   left: 0;
-  top: 64px;
+  top: 0px;
   bottom: 0;
   overflow-y: auto;
+  background-color: var(--admin-bg-navy);
+  padding: 24px 16px;
+  .admin--brand{
+    display: flex;
+    gap: 12px;
+    align-items: center;
+    .brand--logo{
+      width: 36px;
+      height: 36px;
+      border-radius: 8px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      text-align: center;
+      background-color: var(--admin-yellow);
+    }
+    .brand--title{
+      color: #fff;
+      font-size: 15px;
+      display: flex;
+      flex-direction: column;
+      font-weight: 700;
+      span{
+        color: var(--admin-yellow);
+        font-size: 10px;
+        font-weight: 600;
+        letter-spacing: 1.2px;
+      }
+    }
+  }
 
   &::-webkit-scrollbar {
     width: 6px;
@@ -1701,25 +1726,31 @@ footer {
 
 // Admin GNB
 .admin--gnb {
+  margin-top: 28px;
   .admin--gnb-group {
     margin-bottom: 8px;
   }
 
   .admin--gnb-title {
     padding: 12px 24px;
-    font-size: 14px;
-    font-weight: 600;
-    color: var(--admin-text-secondary);
+    font-size: 13px;
+    font-weight: 400;
+    color: var(--admin-text-muted);
     cursor: pointer;
     display: flex;
     justify-content: space-between;
     align-items: center;
     transition: all 0.3s ease;
     user-select: none;
+    font-weight: 400;
+
+    &:has(.admin--gnb-arrow.is-open){
+      color: #fff;
+      font-weight: 600;
+    }
 
     &:hover {
-      color: var(--admin-text-primary);
-      background: var(--admin-bg-primary);
+      color: #fff;
     }
 
     .admin--gnb-arrow {
@@ -1732,6 +1763,31 @@ footer {
     }
   }
 
+  // children 없는 단일 링크 메뉴
+  .admin--gnb-title-link {
+    position: relative;
+    border-radius: 6px;
+    color: var(--admin-text-muted);
+    font-size: 13px;
+    font-weight: 400;
+    &.is-active {
+      color: #fff;
+      background: #262f40;
+      font-weight: 600;
+      &::before{
+        content: '';
+        display: inline-block;
+        position: absolute;
+        top: 0;
+        left: 0;
+        height: 100%;
+        width: 3px;
+        border-radius: 6px;
+        background-color: var(--admin-yellow);
+      }
+    }
+  }
+
   .admin--gnb-submenu {
     list-style: none;
     padding: 0;
@@ -1739,27 +1795,43 @@ footer {
   }
 
   .admin--gnb-item {
+    position: relative;
+    border-radius: 6px;
+    color: var(--admin-text-muted);
+    font-size: 13px;
+    font-weight: 400;
     &.is-active {
       .admin--gnb-link {
-        color: var(--admin-accent-primary);
-        background: rgba(37, 99, 235, 0.1);
-        border-left: 3px solid var(--admin-accent-primary);
+        color: #fff;
+        background: #262f40;
+        font-weight: 600;
+        &::before{
+          content: '';
+          display: inline-block;
+          position: absolute;
+          top: 0;
+          left: 20px;
+          height: 100%;
+          width: 3px;
+          border-radius: 6px;
+          background-color: var(--admin-yellow);
+        }
       }
     }
   }
 
   .admin--gnb-link {
     display: block;
-    padding: 10px 24px 10px 40px;
-    font-size: 14px;
-    color: var(--admin-text-secondary);
+    margin-left: 20px;
+    padding: 12px 24px;
+    font-size: 13px;
+    color: #78808c;
+    border-radius: 6px;
     text-decoration: none;
     transition: all 0.3s ease;
-    border-left: 3px solid transparent;
-
     &:hover {
-      color: var(--admin-text-primary);
-      background: var(--admin-bg-primary);
+      color: #fff;
+      background: #262f40;
     }
   }
 }
@@ -1786,7 +1858,7 @@ footer {
 // Admin Main Content
 .admin--main {
   flex: 1;
-  margin-left: 260px;
+  margin-left: 240px;
   padding: 32px;
   background: var(--admin-bg-primary);
 }

+ 74 - 71
app/layouts/admin.vue

@@ -8,65 +8,50 @@
   const router = useRouter();
 
   // 메뉴 열림 상태 관리
-  const openMenus = ref(["basic", "branch", "staff", "service", "board", "system"]);
+  const openMenus = ref(["dashboard"]);
 
   // GNB 메뉴 구조
   const menuItems = ref([
     {
-      id: "basic",
-      title: "기본정보관리",
-      children: [
-        {
-          title: "사이트 정보",
-          path: "/site-manager/basic/site-info",
-          pattern: /^\/site-manager\/basic\/site-info/,
-        },
-        {
-          title: "팝업관리",
-          path: "/site-manager/basic/popup",
-          pattern: /^\/site-manager\/basic\/popup/,
-        },
-      ],
+      id: "dashboard",
+      title: "📊 대시보드",
+      path: "/site-manager/dashboard",
+    },
+    {
+      id: "admins",
+      title: "🔑 관리자 관리",
+      path: "/site-manager/admins",
     },
     {
       id: "branch",
-      title: "지점관리",
+      title: "🗺️ 분야 및 지역관리",
       children: [
         {
-          title: "딜러사 관리",
+          title: "낚시분야",
           path: "/site-manager/branch/list",
           pattern: /^\/site-manager\/branch\/(list|create|edit)/,
         },
         {
-          title: "전시장목록",
+          title: "지역관리",
           path: "/site-manager/showroom/list",
           pattern: /^\/site-manager\/showroom\/(list|create|edit)/,
         },
-        {
-          title: "서비스센터목록",
-          path: "/site-manager/service-center/list",
-          pattern: /^\/site-manager\/service-center\/(list|create|edit)/,
-        },
       ],
     },
     {
-      id: "board",
-      title: "게시판관리",
+      id: "fishing",
+      title: "⚓ 선상 및 낚시터 관리",
       children: [
         {
-          title: "이벤트",
+          title: "선상관리",
           path: "/site-manager/board/event",
           pattern: /^\/site-manager\/board\/event/,
         },
-        // { title: "뉴스", path: "/site-manager/board/news", pattern: /^\/site-manager\/board\/news/ },
-        // { title: "IR", path: "/site-manager/board/ir", pattern: /^\/site-manager\/board\/ir/ },
-      ],
-    },
-    {
-      id: "system",
-      title: "시스템관리",
-      children: [
-        { title: "관리자관리", path: "/site-manager/admins", pattern: /^\/site-manager\/admins/ },
+        {
+          title: "낚시터관리",
+          path: "/site-manager/board/event",
+          pattern: /^\/site-manager\/board\/event/,
+        }
       ],
     },
   ]);
@@ -96,6 +81,14 @@
     }
 
     for (const menu of menuItems.value) {
+      // children이 없는 단일 메뉴는 자기 자신이 매칭 대상
+      if (!menu.children) {
+        if (menu.path && currentPath === menu.path) {
+          return { menu, child: { title: menu.title, path: menu.path } };
+        }
+        continue;
+      }
+
       for (const child of menu.children) {
         // pattern이 있으면 정규식으로 매칭, 없으면 정확히 일치하는지 확인
         if (child.pattern && child.pattern.test(currentPath)) {
@@ -304,9 +297,8 @@
     <!-- Header -->
     <header class="admin--header">
       <div class="admin--header-left">
-        <div class="admin--logo" @click="goToDashboard" style="cursor: pointer">
-          <h1>파이럿존</h1>
-          <span class="admin--logo-sub">ADMIN</span>
+        <div class="admin--logo">
+          <h1>{{ pageTitle }}</h1>
         </div>
       </div>
       <div class="admin--header-right">
@@ -322,34 +314,54 @@
     </header>
 
     <!-- Main Content Area -->
-    <div class="admin--content-wrapper">
+    <div class="admin--content--wrapper">
       <!-- Sidebar GNB -->
       <aside class="admin--sidebar">
+        <NuxtLink to="/site-manager" class="admin--brand" @click="goToDashboard">
+          <div class="brand--logo">🏴‍☠️</div>
+          <div class="brand--title">
+            <h1>파이럿존</h1>
+            <span>ADMIN</span>
+          </div>
+        </NuxtLink>
         <nav class="admin--gnb">
           <div v-for="menu in menuItems" :key="menu.id" class="admin--gnb-group">
-            <div class="admin--gnb-title" @click="toggleMenu(menu.id)">
+            <!-- children 없는 메뉴: 토글 없이 바로 이동 -->
+            <NuxtLink
+              v-if="!menu.children"
+              :to="menu.path"
+              class="admin--gnb-title admin--gnb-title-link"
+              :class="{ 'is-active': isActiveRoute(menu.path) }"
+            >
               {{ menu.title }}
-              <span
-                class="admin--gnb-arrow"
-                :class="{ 'is-open': openMenus.includes(menu.id) }"
-              >
-                ▼
-              </span>
-            </div>
-            <transition name="admin--submenu">
-              <ul v-show="openMenus.includes(menu.id)" class="admin--gnb-submenu">
-                <li
-                  v-for="submenu in menu.children"
-                  :key="submenu.path"
-                  class="admin--gnb-item"
-                  :class="{ 'is-active': isActiveRoute(submenu.path) }"
+            </NuxtLink>
+
+            <!-- children 있는 메뉴: 기존 토글 동작 -->
+            <template v-else>
+              <div class="admin--gnb-title" @click="toggleMenu(menu.id)">
+                {{ menu.title }}
+                <span
+                  class="admin--gnb-arrow"
+                  :class="{ 'is-open': openMenus.includes(menu.id) }"
                 >
-                  <NuxtLink :to="submenu.path" class="admin--gnb-link">
-                    {{ submenu.title }}
-                  </NuxtLink>
-                </li>
-              </ul>
-            </transition>
+                  ▼
+                </span>
+              </div>
+              <transition name="admin--submenu">
+                <ul v-show="openMenus.includes(menu.id)" class="admin--gnb-submenu">
+                  <li
+                    v-for="submenu in menu.children"
+                    :key="submenu.path"
+                    class="admin--gnb-item"
+                    :class="{ 'is-active': isActiveRoute(submenu.path) }"
+                  >
+                    <NuxtLink :to="submenu.path" class="admin--gnb-link">
+                      {{ submenu.title }}
+                    </NuxtLink>
+                  </li>
+                </ul>
+              </transition>
+            </template>
           </div>
         </nav>
       </aside>
@@ -357,8 +369,7 @@
       <!-- Content Area -->
       <main class="admin--main">
         <!-- Breadcrumb & Title -->
-        <div class="admin--page-header">
-          <h2 class="admin--page-title">{{ pageTitle }}</h2>
+        <!-- <div class="admin--page-header">
           <div class="admin--breadcrumb">
             <span v-for="(crumb, index) in breadcrumbs" :key="index">
               <NuxtLink v-if="crumb.path" :to="crumb.path" class="admin--breadcrumb-link">
@@ -372,20 +383,12 @@
               >
             </span>
           </div>
-        </div>
+        </div> -->
 
         <!-- Page Content -->
         <div class="admin--page-content">
           <slot />
         </div>
-
-        <!-- Admin Footer -->
-        <footer class="admin--footer">
-          <p>
-            &copy; {{ new Date().getFullYear() }} FORDKOREA 포드코리아. All rights
-            reserved.
-          </p>
-        </footer>
       </main>
     </div>
 

+ 0 - 38
app/pages/site-manager/dashboard.vue

@@ -1,44 +1,6 @@
 <template>
   <div class="admin--dashboard">
     <div class="admin--dashboard-stats">
-      <div class="admin--stat-card">
-        <div class="admin--stat-icon">📊</div>
-        <div class="admin--stat-content">
-          <h4>총 팝업</h4>
-          <p class="admin--stat-number">{{ stats.popups }}</p>
-        </div>
-      </div>
-
-      <div class="admin--stat-card">
-        <div class="admin--stat-icon">🏢</div>
-        <div class="admin--stat-content">
-          <h4>총 지점</h4>
-          <p class="admin--stat-number">{{ stats.branches }}</p>
-        </div>
-      </div>
-
-      <div class="admin--stat-card">
-        <div class="admin--stat-icon">👥</div>
-        <div class="admin--stat-content">
-          <h4>총 직원</h4>
-          <p class="admin--stat-number">{{ stats.employees }}</p>
-        </div>
-      </div>
-
-      <div class="admin--stat-card">
-        <div class="admin--stat-icon">📝</div>
-        <div class="admin--stat-content">
-          <h4>브로셔 요청</h4>
-          <p class="admin--stat-number">{{ stats.brochures }}</p>
-        </div>
-      </div>
-    </div>
-
-    <div class="admin--dashboard-recent">
-      <h4>최근 활동</h4>
-      <div class="admin--recent-list">
-        <p class="admin--no-data">최근 활동 내역이 없습니다.</p>
-      </div>
     </div>
   </div>
 </template>