From 32815a0627e67f6c70aadf641af44e409465cc8f Mon Sep 17 00:00:00 2001 From: ttipo Date: Sun, 21 Jun 2026 21:40:30 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83?= =?UTF-8?q?=EC=9D=84=20=EC=82=AC=EC=9D=B4=EB=93=9C=EB=B0=94=20=ED=95=98?= =?UTF-8?q?=EB=8B=A8=20=EC=83=81=EC=8B=9C=20=EB=85=B8=EC=B6=9C=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존 드롭다운 메뉴 안에 숨어 보이지 않던 로그아웃을 항상 노출되는 버튼으로 변경한다. - 사용자 프로필 행은 표시 전용, 아래에 로그아웃 버튼 상시 노출(빨강 호버) - 접힘 시 아이콘만 표시 - 미사용 드롭다운(menuOpen·me-menu·me-overlay) 로직/스타일 제거 Co-Authored-By: Claude Opus 4.8 (1M context) --- frontend/src/layouts/AppShell.vue | 149 +++++++++++++----------------- 1 file changed, 66 insertions(+), 83 deletions(-) diff --git a/frontend/src/layouts/AppShell.vue b/frontend/src/layouts/AppShell.vue index 9859959..5a6dd5f 100644 --- a/frontend/src/layouts/AppShell.vue +++ b/frontend/src/layouts/AppShell.vue @@ -35,9 +35,6 @@ const activeNav = computed<'tasks' | 'projects'>(() => // 현재 로그인 사용자(프로필 아바타는 UserAvatar 가 이미지/placeholder 로 표시) const me = computed(() => authStore.user) -// 사용자 메뉴 토글 -const menuOpen = ref(false) - // --- 알림(실시간 SSE) --- const notiStore = useNotificationStore() const { @@ -73,7 +70,6 @@ onMounted(() => { // 로그아웃 → 알림 스트림 해제 후 로그인 화면으로 async function onLogout() { - menuOpen.value = false notiStore.disconnect() await authStore.logout() await router.push('/login') @@ -198,14 +194,9 @@ async function onLogout() { > 사이드바 접기 - - - -
+ +
@@ -451,7 +444,7 @@ async function onLogout() { .shell.collapsed .nav-item span { display: none; } -.shell.collapsed .side-me { +.shell.collapsed .side-user { justify-content: center; padding-left: 0; padding-right: 0; @@ -459,6 +452,14 @@ async function onLogout() { .shell.collapsed .side-me-text { display: none; } +.shell.collapsed .logout-btn { + justify-content: center; + padding-left: 0; + padding-right: 0; +} +.shell.collapsed .logout-btn span { + display: none; +} .shell.collapsed .collapse-btn { justify-content: center; padding-left: 0; @@ -470,11 +471,6 @@ async function onLogout() { .shell.collapsed .collapse-btn svg { transform: rotate(180deg); } -/* 접힘 상태에서 사용자 메뉴는 레일 오른쪽으로 펼침 */ -.shell.collapsed .side-menu { - left: 0.5rem; - right: auto; -} .brand { display: flex; @@ -569,25 +565,44 @@ async function onLogout() { flex-shrink: 0; transition: transform 0.18s ease; } -.side-me { +.side-user { display: flex; align-items: center; gap: 0.5625rem; width: 100%; padding: 0.4375rem 0.5rem; +} +.side-user > :first-child { + width: 1.875rem; + height: 1.875rem; + flex-shrink: 0; +} +/* 로그아웃 — 항상 노출되는 버튼 */ +.logout-btn { + display: flex; + align-items: center; + gap: 0.6875rem; + width: 100%; + margin-top: 0.25rem; + padding: 0.5rem 0.75rem; border: none; background: transparent; border-radius: var(--radius); + color: var(--text-2); cursor: pointer; font-family: inherit; - text-align: left; + font-size: 0.8125rem; + font-weight: 500; + line-height: 1; + white-space: nowrap; } -.side-me:hover { - background: #f1f2f4; +.logout-btn:hover { + background: var(--red-weak); + color: var(--red); } -.side-me > :first-child { - width: 1.875rem; - height: 1.875rem; +.logout-btn svg { + width: 1.125rem; + height: 1.125rem; flex-shrink: 0; } .side-me-text { @@ -823,43 +838,6 @@ async function onLogout() { z-index: 55; } -/* 사용자 드롭다운(사이드바 하단 → 위로 펼침) */ -.me-menu { - position: absolute; - z-index: 60; - min-width: 11rem; - background: var(--panel); - border: 1px solid var(--border); - border-radius: var(--radius-sm); - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); - overflow: hidden; -} -.side-menu { - left: 0.625rem; - right: 0.625rem; - bottom: calc(100% - 0.25rem); -} -.me-action { - width: 100%; - text-align: left; - padding: 0.625rem 0.875rem; - border: none; - background: transparent; - font-family: inherit; - font-size: 0.844rem; - color: var(--text); - cursor: pointer; -} -.me-action:hover { - background: #f1f2f4; -} -/* 메뉴 바깥 클릭 감지용 투명 오버레이 */ -.me-overlay { - position: fixed; - inset: 0; - z-index: 55; -} - /* 햄버거(모바일 전용) / 드로어 배경 — 데스크톱에서는 숨김 */ .hamburger { display: none; @@ -896,7 +874,8 @@ async function onLogout() { /* 접힘 축소 규칙 무효화(드로어는 항상 펼친 모양) */ .shell.collapsed .brand, .shell.collapsed .nav-item, - .shell.collapsed .side-me, + .shell.collapsed .side-user, + .shell.collapsed .logout-btn, .shell.collapsed .collapse-btn { justify-content: flex-start; padding-left: 0.75rem; @@ -904,7 +883,7 @@ async function onLogout() { } .shell.collapsed .brand-name, .shell.collapsed .nav-item span, - .shell.collapsed .side-me-text { + .shell.collapsed .logout-btn span { display: inline; } .shell.collapsed .side-me-text { @@ -913,6 +892,10 @@ async function onLogout() { .shell.collapsed .brand { padding-left: 1.125rem; } + .shell.collapsed .side-user { + padding-left: 0.5rem; + padding-right: 0.5rem; + } .sidebar-backdrop { display: block; position: fixed;