diff --git a/HANDOFF.md b/HANDOFF.md index 83461fa..368faab 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -4,7 +4,7 @@ - 프로젝트명: 10 Minute Planner 웹 UI - 기술 스택: Vue 3 + Vite + TailwindCSS + JavaScript -- 현재 기준 버전: `v0.1.29` 준비 중 +- 현재 기준 버전: `v0.1.30` 준비 중 - Git 원격 저장소: `https://git.sori.studio/zenn/planner.sori.studio.git` ## 기준 디자인 @@ -173,6 +173,8 @@ - 플래너 집중 보기 반응형 기준은 `1620px 이상: 우측 패널 2열`, `1280px 이상 ~ 1619px 이하: 우측 패널 1열 + 최대 360px`, `1280px 미만: 우측 패널 오버레이` 구조로 다시 정리했다. - 오버레이 구간에서는 본문 오른쪽 위의 `OPEN SIDE PANEL` 버튼으로 패널을 열고, 배경 클릭이나 `CLOSE` 버튼으로 닫는다. - `2 PAGE SPREAD`는 화면 폭을 기준으로 배율을 자동 계산해서 오른쪽 페이지가 잘리는 현상을 줄이는 방향으로 조정했다. +- `1280px` 미만에서는 왼쪽 내비게이션도 본문 위에 쌓이지 않고 `MENU` 버튼으로 여는 드로어형 패널로 전환된다. +- 태블릿/모바일 구간에서는 `왼쪽 내비게이션 드로어 + 오른쪽 정보 패널 오버레이 + 본문 단일 컬럼` 조합으로 보는 흐름을 기본값으로 삼는다. - 비로그인 랜딩 카드는 상단 고정이 아니라 화면 중앙에 오도록 정렬을 수정했다. - 현재 환경에서는 Docker 데몬이 꺼져 있어서 `docker compose build` 실검증은 하지 못했고, 데몬 시작 후 다시 확인이 필요하다. - 이미지 저장 기능은 추후 `print-only` 또는 별도 export 전용 레이아웃을 기준으로 구현하면 화면/인쇄/공유 결과를 맞추기 쉽다. diff --git a/package-lock.json b/package-lock.json index 8cd99d9..f272abb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ten-minute-planner", - "version": "0.1.29", + "version": "0.1.30", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ten-minute-planner", - "version": "0.1.29", + "version": "0.1.30", "dependencies": { "vue": "^3.5.13" }, diff --git a/package.json b/package.json index 8c7805f..8c0e4f2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ten-minute-planner", "private": true, - "version": "0.1.29", + "version": "0.1.30", "type": "module", "scripts": { "dev": "vite", diff --git a/src/App.vue b/src/App.vue index d508c82..87a0f5e 100644 --- a/src/App.vue +++ b/src/App.vue @@ -46,6 +46,7 @@ const syncToastVisible = ref(false) const selectedDate = ref(new Date()) const calendarViewDate = ref(new Date(selectedDate.value)) const windowWidth = ref(typeof window === 'undefined' ? 1920 : window.innerWidth) +const leftPanelOpen = ref(false) const rightPanelOpen = ref(false) const statsRangeStart = ref(toKey(new Date(new Date().setDate(new Date().getDate() - 6)))) const statsRangeEnd = ref(toKey(new Date())) @@ -691,6 +692,8 @@ const readNextItems = computed(() => { const isWideFocusSidebar = computed(() => windowWidth.value >= 1620) const isOverlayFocusSidebar = computed(() => windowWidth.value < 1280) +const showInlineLeftSidebar = computed(() => windowWidth.value >= 1280) +const isCompactMobile = computed(() => windowWidth.value < 800) const showInlineFocusSidebar = computed(() => !isOverlayFocusSidebar.value) const focusSidebarOuterClass = computed(() => showInlineFocusSidebar.value @@ -783,10 +786,19 @@ function updateWindowWidth() { windowWidth.value = window.innerWidth if (windowWidth.value >= 1280) { + leftPanelOpen.value = false rightPanelOpen.value = false } } +function openLeftPanel() { + leftPanelOpen.value = true +} + +function closeLeftPanel() { + leftPanelOpen.value = false +} + function openRightPanel() { rightPanelOpen.value = true } @@ -795,6 +807,16 @@ function closeRightPanel() { rightPanelOpen.value = false } +function setScreenMode(mode) { + screenMode.value = mode + closeLeftPanel() +} + +function setViewMode(mode) { + viewMode.value = mode + closeLeftPanel() +} + function setSyncFeedback(status, message, options = {}) { const { visible = true, @@ -1372,11 +1394,57 @@ onBeforeUnmount(() => { class="print-root mx-auto flex max-w-[1760px] flex-col gap-6" :class="isAuthenticated ? 'xl:h-[calc(100vh-3rem)] xl:grid xl:grid-cols-[300px_minmax(0,1fr)] xl:items-start' : 'min-h-[calc(100vh-3rem)] items-center justify-center'" > + + +
+