|
|
|
|
@@ -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'"
|
|
|
|
|
>
|
|
|
|
|
<section
|
|
|
|
|
v-if="isAuthenticated && !showInlineLeftSidebar"
|
|
|
|
|
class="print-hidden rounded-[28px] border border-white/60 bg-white/78 p-4 shadow-[0_18px_60px_rgba(28,25,23,0.08)] backdrop-blur"
|
|
|
|
|
>
|
|
|
|
|
<div class="flex items-start justify-between gap-4">
|
|
|
|
|
<div>
|
|
|
|
|
<p class="text-[10px] font-bold uppercase tracking-[0.22em] text-stone-500">10 Minute Planner</p>
|
|
|
|
|
<p class="mt-2 text-lg font-semibold tracking-[-0.04em] text-stone-900">
|
|
|
|
|
{{ screenMode.toUpperCase() }}
|
|
|
|
|
</p>
|
|
|
|
|
<p class="mt-1 text-[11px] font-semibold text-stone-500">
|
|
|
|
|
{{ currentUser?.nickname }} 님의 플래너
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
class="rounded-full border border-stone-200 bg-white px-4 py-2 text-[11px] font-bold tracking-[0.16em] text-stone-700 transition hover:border-stone-400 hover:text-ink"
|
|
|
|
|
@click="openLeftPanel"
|
|
|
|
|
>
|
|
|
|
|
MENU
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
v-if="isAuthenticated && !showInlineLeftSidebar && leftPanelOpen"
|
|
|
|
|
class="fixed inset-0 z-40 bg-stone-900/22 backdrop-blur-[2px]"
|
|
|
|
|
@click="closeLeftPanel"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<aside
|
|
|
|
|
v-if="isAuthenticated"
|
|
|
|
|
class="scrollbar-hide print-hidden rounded-[28px] border border-white/60 bg-white/70 p-5 backdrop-blur sm:p-6 xl:h-full xl:overflow-y-auto"
|
|
|
|
|
class="scrollbar-hide print-hidden rounded-[28px] border border-white/60 bg-white/70 p-5 backdrop-blur sm:p-6"
|
|
|
|
|
:class="showInlineLeftSidebar ? 'xl:h-full xl:overflow-y-auto' : 'fixed inset-y-4 left-4 z-50 w-[min(360px,calc(100vw-2rem))] overflow-y-auto shadow-[0_18px_60px_rgba(28,25,23,0.14)]'"
|
|
|
|
|
v-show="showInlineLeftSidebar || leftPanelOpen"
|
|
|
|
|
>
|
|
|
|
|
<div class="space-y-6">
|
|
|
|
|
<div v-if="!showInlineLeftSidebar" class="flex items-center justify-between rounded-[20px] border border-stone-200 bg-white/85 px-4 py-3">
|
|
|
|
|
<div>
|
|
|
|
|
<p class="text-[10px] font-bold uppercase tracking-[0.2em] text-stone-500">Navigation</p>
|
|
|
|
|
<p class="mt-1 text-sm font-semibold text-stone-900">{{ currentUser?.nickname }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
class="rounded-full border border-stone-200 px-3 py-1 text-[10px] font-bold tracking-[0.14em] text-stone-600 transition hover:border-stone-400 hover:text-ink"
|
|
|
|
|
@click="closeLeftPanel"
|
|
|
|
|
>
|
|
|
|
|
CLOSE
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="space-y-2">
|
|
|
|
|
<p class="text-[11px] font-bold uppercase tracking-[0.28em] text-stone-500">10 Minute Planner</p>
|
|
|
|
|
<h1 class="text-2xl font-semibold tracking-[-0.04em] text-stone-900">
|
|
|
|
|
@@ -1431,7 +1499,7 @@ onBeforeUnmount(() => {
|
|
|
|
|
type="button"
|
|
|
|
|
class="rounded-[20px] border px-4 py-4 text-left transition"
|
|
|
|
|
:class="screenMode === 'planner' ? 'border-stone-900 bg-stone-900 text-white shadow-[0_12px_24px_rgba(28,25,23,0.18)]' : 'border-stone-200 bg-white text-stone-700 hover:border-stone-400'"
|
|
|
|
|
@click="screenMode = 'planner'"
|
|
|
|
|
@click="setScreenMode('planner')"
|
|
|
|
|
>
|
|
|
|
|
<p class="text-xs font-bold tracking-[0.18em]">PLANNER</p>
|
|
|
|
|
<p class="mt-1 text-[11px] font-semibold tracking-[0.04em]" :class="screenMode === 'planner' ? 'text-stone-200' : 'text-stone-500'">오늘 문서 작성과 캘린더 이동</p>
|
|
|
|
|
@@ -1440,7 +1508,7 @@ onBeforeUnmount(() => {
|
|
|
|
|
type="button"
|
|
|
|
|
class="rounded-[20px] border px-4 py-4 text-left transition"
|
|
|
|
|
:class="screenMode === 'stats' ? 'border-stone-900 bg-stone-900 text-white shadow-[0_12px_24px_rgba(28,25,23,0.18)]' : 'border-stone-200 bg-white text-stone-700 hover:border-stone-400'"
|
|
|
|
|
@click="screenMode = 'stats'"
|
|
|
|
|
@click="setScreenMode('stats')"
|
|
|
|
|
>
|
|
|
|
|
<p class="text-xs font-bold tracking-[0.18em]">STATS</p>
|
|
|
|
|
<p class="mt-1 text-[11px] font-semibold tracking-[0.04em]" :class="screenMode === 'stats' ? 'text-stone-200' : 'text-stone-500'">기간별 집중 시간과 완료율</p>
|
|
|
|
|
@@ -1449,7 +1517,7 @@ onBeforeUnmount(() => {
|
|
|
|
|
type="button"
|
|
|
|
|
class="rounded-[20px] border px-4 py-4 text-left transition"
|
|
|
|
|
:class="screenMode === 'goals' ? 'border-stone-900 bg-stone-900 text-white shadow-[0_12px_24px_rgba(28,25,23,0.18)]' : 'border-stone-200 bg-white text-stone-700 hover:border-stone-400'"
|
|
|
|
|
@click="screenMode = 'goals'"
|
|
|
|
|
@click="setScreenMode('goals')"
|
|
|
|
|
>
|
|
|
|
|
<p class="text-xs font-bold tracking-[0.18em]">GOALS</p>
|
|
|
|
|
<p class="mt-1 text-[11px] font-semibold tracking-[0.04em]" :class="screenMode === 'goals' ? 'text-stone-200' : 'text-stone-500'">D-DAY 목표와 표시 기간 관리</p>
|
|
|
|
|
@@ -1458,7 +1526,7 @@ onBeforeUnmount(() => {
|
|
|
|
|
type="button"
|
|
|
|
|
class="rounded-[20px] border px-4 py-4 text-left transition"
|
|
|
|
|
:class="screenMode === 'settings' ? 'border-stone-900 bg-stone-900 text-white shadow-[0_12px_24px_rgba(28,25,23,0.18)]' : 'border-stone-200 bg-white text-stone-700 hover:border-stone-400'"
|
|
|
|
|
@click="screenMode = 'settings'"
|
|
|
|
|
@click="setScreenMode('settings')"
|
|
|
|
|
>
|
|
|
|
|
<p class="text-xs font-bold tracking-[0.18em]">SETTINGS</p>
|
|
|
|
|
<p class="mt-1 text-[11px] font-semibold tracking-[0.04em]" :class="screenMode === 'settings' ? 'text-stone-200' : 'text-stone-500'">계정 정보와 비밀번호 수정</p>
|
|
|
|
|
@@ -1473,7 +1541,7 @@ onBeforeUnmount(() => {
|
|
|
|
|
type="button"
|
|
|
|
|
class="rounded-2xl px-4 py-3 text-xs font-bold tracking-[0.14em] transition"
|
|
|
|
|
:class="viewMode === 'focus' ? 'bg-stone-900 text-white' : 'bg-stone-100 text-stone-500'"
|
|
|
|
|
@click="viewMode = 'focus'"
|
|
|
|
|
@click="setViewMode('focus')"
|
|
|
|
|
>
|
|
|
|
|
1 PAGE + INFO
|
|
|
|
|
</button>
|
|
|
|
|
@@ -1481,7 +1549,7 @@ onBeforeUnmount(() => {
|
|
|
|
|
type="button"
|
|
|
|
|
class="rounded-2xl px-4 py-3 text-xs font-bold tracking-[0.14em] transition"
|
|
|
|
|
:class="viewMode === 'spread' ? 'bg-stone-900 text-white' : 'bg-stone-100 text-stone-500'"
|
|
|
|
|
@click="viewMode = 'spread'"
|
|
|
|
|
@click="setViewMode('spread')"
|
|
|
|
|
>
|
|
|
|
|
2 PAGE SPREAD
|
|
|
|
|
</button>
|
|
|
|
|
|