v0.1.7 - 저장 레이어 분리 시작
This commit is contained in:
102
src/App.vue
102
src/App.vue
@@ -3,8 +3,12 @@ import { computed, reactive, ref, watch, nextTick } from 'vue'
|
||||
import MiniCalendar from './components/MiniCalendar.vue'
|
||||
import PlannerPage from './components/PlannerPage.vue'
|
||||
import StatsDashboard from './components/StatsDashboard.vue'
|
||||
import {
|
||||
createInitialPlannerRecords,
|
||||
persistPlannerState,
|
||||
restorePlannerUiState,
|
||||
} from './lib/plannerStorage'
|
||||
|
||||
const STORAGE_KEY = 'ten-minute-planner-state'
|
||||
const screenMode = ref('planner')
|
||||
const viewMode = ref('focus')
|
||||
const printLayout = ref('single')
|
||||
@@ -190,62 +194,15 @@ function normalizeRecord(record) {
|
||||
}
|
||||
}
|
||||
|
||||
function createInitialPlannerRecords() {
|
||||
const baseRecords = Object.fromEntries(
|
||||
Object.entries(plannerSeed).map(([key, record]) => [key, normalizeRecord(record)]),
|
||||
)
|
||||
const plannerRecords = reactive(createInitialPlannerRecords(plannerSeed, normalizeRecord))
|
||||
|
||||
if (typeof window === 'undefined') {
|
||||
return baseRecords
|
||||
}
|
||||
|
||||
try {
|
||||
const savedState = JSON.parse(window.localStorage.getItem(STORAGE_KEY) ?? '{}')
|
||||
const savedRecords = savedState.records ?? {}
|
||||
|
||||
Object.entries(savedRecords).forEach(([key, record]) => {
|
||||
baseRecords[key] = normalizeRecord(record)
|
||||
})
|
||||
} catch (error) {
|
||||
console.warn('저장된 플래너 상태를 불러오지 못했습니다.', error)
|
||||
}
|
||||
|
||||
return baseRecords
|
||||
}
|
||||
|
||||
const plannerRecords = reactive(createInitialPlannerRecords())
|
||||
|
||||
function restoreDateState() {
|
||||
if (typeof window === 'undefined') {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const savedState = JSON.parse(window.localStorage.getItem(STORAGE_KEY) ?? '{}')
|
||||
|
||||
if (savedState.selectedDate) {
|
||||
selectedDate.value = toDateValue(savedState.selectedDate, selectedDate.value)
|
||||
}
|
||||
|
||||
if (savedState.calendarViewDate) {
|
||||
calendarViewDate.value = toDateValue(savedState.calendarViewDate, selectedDate.value)
|
||||
} else {
|
||||
calendarViewDate.value = new Date(selectedDate.value)
|
||||
}
|
||||
|
||||
if (savedState.statsRangeStart) {
|
||||
statsRangeStart.value = savedState.statsRangeStart
|
||||
}
|
||||
|
||||
if (savedState.statsRangeEnd) {
|
||||
statsRangeEnd.value = savedState.statsRangeEnd
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('저장된 날짜 상태를 불러오지 못했습니다.', error)
|
||||
}
|
||||
}
|
||||
|
||||
restoreDateState()
|
||||
restorePlannerUiState({
|
||||
selectedDate,
|
||||
calendarViewDate,
|
||||
statsRangeStart,
|
||||
statsRangeEnd,
|
||||
toDateValue,
|
||||
})
|
||||
|
||||
function getPlannerRecord(date) {
|
||||
const key = toKey(date)
|
||||
@@ -560,32 +517,13 @@ const bestDay = computed(() => {
|
||||
watch(
|
||||
[plannerRecords, selectedDate, calendarViewDate, statsRangeStart, statsRangeEnd],
|
||||
() => {
|
||||
if (typeof window === 'undefined') {
|
||||
return
|
||||
}
|
||||
|
||||
const serializableRecords = Object.fromEntries(
|
||||
Object.entries(plannerRecords).map(([key, record]) => [
|
||||
key,
|
||||
{
|
||||
...record,
|
||||
tasks: record.tasks.map((task) => ({ ...task })),
|
||||
memo: record.memo.map((item) => ({ ...item })),
|
||||
timetable: [...record.timetable],
|
||||
},
|
||||
]),
|
||||
)
|
||||
|
||||
window.localStorage.setItem(
|
||||
STORAGE_KEY,
|
||||
JSON.stringify({
|
||||
selectedDate: selectedDate.value.toISOString(),
|
||||
calendarViewDate: calendarViewDate.value.toISOString(),
|
||||
statsRangeStart: normalizedStatsRange.value.startKey,
|
||||
statsRangeEnd: normalizedStatsRange.value.endKey,
|
||||
records: serializableRecords,
|
||||
}),
|
||||
)
|
||||
persistPlannerState({
|
||||
plannerRecords,
|
||||
selectedDate: selectedDate.value,
|
||||
calendarViewDate: calendarViewDate.value,
|
||||
statsRangeStart: normalizedStatsRange.value.startKey,
|
||||
statsRangeEnd: normalizedStatsRange.value.endKey,
|
||||
})
|
||||
},
|
||||
{ deep: true },
|
||||
)
|
||||
|
||||
92
src/lib/plannerStorage.js
Normal file
92
src/lib/plannerStorage.js
Normal file
@@ -0,0 +1,92 @@
|
||||
const STORAGE_KEY = 'ten-minute-planner-state'
|
||||
|
||||
function readStorageState() {
|
||||
if (typeof window === 'undefined') {
|
||||
return {}
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(window.localStorage.getItem(STORAGE_KEY) ?? '{}')
|
||||
} catch (error) {
|
||||
console.warn('저장된 플래너 상태를 불러오지 못했습니다.', error)
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
export function createInitialPlannerRecords(seedRecords, normalizeRecord) {
|
||||
const baseRecords = Object.fromEntries(
|
||||
Object.entries(seedRecords).map(([key, record]) => [key, normalizeRecord(record)]),
|
||||
)
|
||||
|
||||
const savedState = readStorageState()
|
||||
const savedRecords = savedState.records ?? {}
|
||||
|
||||
Object.entries(savedRecords).forEach(([key, record]) => {
|
||||
baseRecords[key] = normalizeRecord(record)
|
||||
})
|
||||
|
||||
return baseRecords
|
||||
}
|
||||
|
||||
export function restorePlannerUiState({
|
||||
selectedDate,
|
||||
calendarViewDate,
|
||||
statsRangeStart,
|
||||
statsRangeEnd,
|
||||
toDateValue,
|
||||
}) {
|
||||
const savedState = readStorageState()
|
||||
|
||||
if (savedState.selectedDate) {
|
||||
selectedDate.value = toDateValue(savedState.selectedDate, selectedDate.value)
|
||||
}
|
||||
|
||||
if (savedState.calendarViewDate) {
|
||||
calendarViewDate.value = toDateValue(savedState.calendarViewDate, selectedDate.value)
|
||||
} else {
|
||||
calendarViewDate.value = new Date(selectedDate.value)
|
||||
}
|
||||
|
||||
if (savedState.statsRangeStart) {
|
||||
statsRangeStart.value = savedState.statsRangeStart
|
||||
}
|
||||
|
||||
if (savedState.statsRangeEnd) {
|
||||
statsRangeEnd.value = savedState.statsRangeEnd
|
||||
}
|
||||
}
|
||||
|
||||
export function persistPlannerState({
|
||||
plannerRecords,
|
||||
selectedDate,
|
||||
calendarViewDate,
|
||||
statsRangeStart,
|
||||
statsRangeEnd,
|
||||
}) {
|
||||
if (typeof window === 'undefined') {
|
||||
return
|
||||
}
|
||||
|
||||
const serializableRecords = Object.fromEntries(
|
||||
Object.entries(plannerRecords).map(([key, record]) => [
|
||||
key,
|
||||
{
|
||||
...record,
|
||||
tasks: record.tasks.map((task) => ({ ...task })),
|
||||
memo: record.memo.map((item) => ({ ...item })),
|
||||
timetable: [...record.timetable],
|
||||
},
|
||||
]),
|
||||
)
|
||||
|
||||
window.localStorage.setItem(
|
||||
STORAGE_KEY,
|
||||
JSON.stringify({
|
||||
selectedDate: selectedDate.toISOString(),
|
||||
calendarViewDate: calendarViewDate.toISOString(),
|
||||
statsRangeStart,
|
||||
statsRangeEnd,
|
||||
records: serializableRecords,
|
||||
}),
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user