diff --git a/frontend/src/features/liberation/Liberation.jsx b/frontend/src/features/liberation/Liberation.jsx index 24b9634..425cbe6 100644 --- a/frontend/src/features/liberation/Liberation.jsx +++ b/frontend/src/features/liberation/Liberation.jsx @@ -93,43 +93,46 @@ export default function Liberation() { staleTime: Infinity, }) - const [state, setState] = useState(() => { + const makeInitialSlot = () => ({ + startChapter: 0, + currentPoints: 0, + startDate: dayjs(todayKST()).toISOString(), + weekly: makeEmptyWeekly(), + weekOverrides: {}, + weeks: [makeEmptyWeek(todayKST())], + }) + + const [root, setRoot] = useState(() => { const saved = localStorage.getItem(STORAGE_KEY) if (saved) { try { const parsed = JSON.parse(saved) - if (!parsed.weekly) parsed.weekly = makeEmptyWeekly() - if (!parsed.startDate) parsed.startDate = dayjs(todayKST()).toISOString() - if (!parsed.weekOverrides) parsed.weekOverrides = {} - // enabled/'none' 필드 제거 마이그레이션 - const migrate = (sel, defaultDiff) => { - if (!sel) return sel - if (!sel.difficulty || sel.difficulty === 'none') sel.difficulty = defaultDiff - delete sel.enabled - return sel + // 구버전(단일 slot) → 새 구조로 마이그레이션 + if (!parsed.calcMode) { + if (!parsed.weekly) parsed.weekly = makeEmptyWeekly() + if (!parsed.startDate) parsed.startDate = dayjs(todayKST()).toISOString() + if (!parsed.weekOverrides) parsed.weekOverrides = {} + return { calcMode: 'simple', simple: parsed, weekly: makeInitialSlot() } } - WEEKLY_BOSSES.forEach((b) => { - if (parsed.weekly.bosses?.[b.key]) { - parsed.weekly.bosses[b.key] = migrate(parsed.weekly.bosses[b.key], b.difficulties[0].key) - } - }) - parsed.weekly.blackMage = migrate(parsed.weekly.blackMage, MONTHLY_BOSSES[0].difficulties[0].key) return parsed } catch { /* ignore */ } } - return { - startChapter: 0, - currentPoints: 0, - startDate: dayjs(todayKST()).toISOString(), - weekly: makeEmptyWeekly(), - weekOverrides: {}, - weeks: [makeEmptyWeek(todayKST())], - } + return { calcMode: 'simple', simple: makeInitialSlot(), weekly: makeInitialSlot() } }) + const calcMode = root.calcMode + const state = root[calcMode] + const setState = (updater) => { + setRoot((prev) => ({ + ...prev, + [prev.calcMode]: typeof updater === 'function' ? updater(prev[prev.calcMode]) : updater, + })) + } + const setCalcMode = (mode) => setRoot((prev) => ({ ...prev, calcMode: mode })) + useEffect(() => { - localStorage.setItem(STORAGE_KEY, JSON.stringify(state)) - }, [state]) + localStorage.setItem(STORAGE_KEY, JSON.stringify(root)) + }, [root]) // 주차별 계산 const progressByWeek = useMemo(() => { @@ -260,14 +263,7 @@ export default function Liberation() { const [resetOpen, setResetOpen] = useState(false) const doReset = () => { - setState({ - startChapter: 0, - currentPoints: 0, - startDate: dayjs(todayKST()).toISOString(), - weekly: makeEmptyWeekly(), - weekOverrides: {}, - weeks: [makeEmptyWeek(todayKST())], - }) + setState(makeInitialSlot()) setResetOpen(false) } @@ -315,6 +311,27 @@ export default function Liberation() {