diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index 6393d8c..fb73bd1 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -3,7 +3,7 @@ import { browser } from '$app/environment'; import { page } from '$app/stores'; import { goto } from '$app/navigation'; - import { Menu, EllipsisVertical } from 'lucide-svelte'; + import { Menu, EllipsisVertical, ChevronDown, FileText, Newspaper, HelpCircle, StickyNote, Inbox } from 'lucide-svelte'; import { isAuthenticated, user, tryRefresh, logout } from '$lib/stores/auth'; import { toasts, removeToast } from '$lib/stores/toast'; import { refresh as refreshPublicConfig } from '$lib/stores/config'; @@ -11,13 +11,14 @@ import Sidebar from '$lib/components/Sidebar.svelte'; import SystemStatusDot from '$lib/components/SystemStatusDot.svelte'; import QuickMemoButton from '$lib/components/QuickMemoButton.svelte'; - import Button from '$lib/components/ui/Button.svelte'; import IconButton from '$lib/components/ui/IconButton.svelte'; import Drawer from '$lib/components/ui/Drawer.svelte'; import '../app.css'; const PUBLIC_PATHS = ['/login', '/setup', '/__styleguide']; const NO_CHROME_PATHS = ['/login', '/setup', '/__styleguide']; + // /news = 풀스크린 브리핑 → 데스크탑 상시 사이드바 없음 + const NO_SIDEBAR_PATHS = ['/news']; // toast 의미 토큰 매핑 (A-8 B3) const TOAST_CLASS = { @@ -28,18 +29,21 @@ }; let authChecked = $state(false); - let menuOpen = $state(false); + let menuOpen = $state(false); // ⋮ 설정 메뉴 + let navMenu = $state(''); // '' | 'docs' | 'news' — 상단 드롭다운 function isActive(path) { return $page.url.pathname.startsWith(path); } + // 그룹 active + let docsActive = $derived(['/documents', '/library', '/audio', '/video'].some(isActive)); + let newsActive = $derived(['/news', '/digest'].some(isActive)); onMount(async () => { if (!$isAuthenticated) { await tryRefresh(); } authChecked = true; - // 공개 설정 prewarm (인증 상태와 독립적). 실패 시 fallback 유지. void refreshPublicConfig(); }); @@ -50,6 +54,7 @@ }); let showChrome = $derived($isAuthenticated && !NO_CHROME_PATHS.some(p => $page.url.pathname.startsWith(p))); + let showSidebar = $derived(showChrome && !NO_SIDEBAR_PATHS.some(p => $page.url.pathname.startsWith(p))); function handleKeydown(e) { if (e.key === '/' && !['INPUT', 'TEXTAREA'].includes(document.activeElement?.tagName)) { @@ -57,10 +62,12 @@ document.querySelector('[data-search-input]')?.focus(); } if (e.key === 'Escape') { - // 5대 원칙 #2 — 글로벌 Esc는 uiState에 위임 (modal stack → drawer 우선순위 자동 처리) ui.handleEscape(); + navMenu = ''; + menuOpen = false; } } + function nav(path) { navMenu = ''; goto(path); } @@ -73,81 +80,102 @@ {#if showChrome}
-