From 73c024b7a70d1370009b46c5044b3d19b270803f Mon Sep 17 00:00:00 2001 From: caadiq Date: Wed, 15 Apr 2026 14:06:01 +0900 Subject: [PATCH] =?UTF-8?q?=EC=8B=AC=EB=B3=BC=20=EA=B3=84=EC=82=B0?= =?UTF-8?q?=EA=B8=B0=EC=97=90=20zustand=20=EB=8F=84=EC=9E=85=20+=20?= =?UTF-8?q?=EC=BA=90=EB=A6=AD=ED=84=B0=EB=B3=84=20=EC=83=81=ED=83=9C=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - zustand + persist 미들웨어로 캐릭터 목록·선택 상태·심볼 진행 저장 - 스토어 스키마: progress[charId][symbolId] = { level, growth, daily, weeklyCount, extra, dailyDone } - Symbol.jsx가 localStorage useState 코드 대신 useSymbolStore 사용 - SymbolCard가 charId 기반으로 값 읽기/업데이트 - 닉네임 입력/조회 버튼 높이 정렬 (border-2 → border + box-border) Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/package-lock.json | 32 ++++++++- frontend/package.json | 3 +- frontend/src/features/symbol/Symbol.jsx | 82 ++++++++++------------- frontend/src/features/symbol/store.js | 87 +++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 48 deletions(-) create mode 100644 frontend/src/features/symbol/store.js diff --git a/frontend/package-lock.json b/frontend/package-lock.json index fcd56ef..f53da44 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -18,7 +18,8 @@ "overlayscrollbars-react": "^0.5.6", "react": "^19.2.4", "react-dom": "^19.2.4", - "react-router-dom": "^7.14.0" + "react-router-dom": "^7.14.0", + "zustand": "^5.0.12" }, "devDependencies": { "@eslint/js": "^9.39.4", @@ -3139,6 +3140,35 @@ "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } + }, + "node_modules/zustand": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.12.tgz", + "integrity": "sha512-i77ae3aZq4dhMlRhJVCYgMLKuSiZAaUPAct2AksxQ+gOtimhGMdXljRT21P5BNpeT4kXlLIckvkPM029OljD7g==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } } } } diff --git a/frontend/package.json b/frontend/package.json index c6606a8..b6f5333 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -20,7 +20,8 @@ "overlayscrollbars-react": "^0.5.6", "react": "^19.2.4", "react-dom": "^19.2.4", - "react-router-dom": "^7.14.0" + "react-router-dom": "^7.14.0", + "zustand": "^5.0.12" }, "devDependencies": { "@eslint/js": "^9.39.4", diff --git a/frontend/src/features/symbol/Symbol.jsx b/frontend/src/features/symbol/Symbol.jsx index ff45795..f3d544e 100644 --- a/frontend/src/features/symbol/Symbol.jsx +++ b/frontend/src/features/symbol/Symbol.jsx @@ -3,7 +3,7 @@ import { useQuery, useMutation } from '@tanstack/react-query' import { api } from '../../api/client' import { useLayout } from '../../components/Layout' import Select from '../../components/Select' - +import { useSymbolStore } from './store' const TYPE_ORDER = ['아케인', '어센틱', '그랜드 어센틱'] @@ -57,12 +57,19 @@ function CharacterCard({ char, active, onSelect, onRemove }) { ) } -function SymbolCard({ symbol, equipped }) { - const [weeklyCount, setWeeklyCount] = useState(3) - const [dailyDone, setDailyDone] = useState(false) +function SymbolCard({ symbol, equipped, charId }) { + const progress = useSymbolStore((s) => s.progress?.[charId]?.[symbol.id]) + const updateSymbol = useSymbolStore((s) => s.updateSymbol) + + const dailyDone = progress?.dailyDone ?? false + const weeklyCount = progress?.weeklyCount ?? 3 + const daily = progress?.daily ?? symbol.daily_default + const extra = progress?.extra ?? 0 + const patch = (p) => charId && updateSymbol(charId, symbol.id, p) + // 임시 목업 값 (계산 기능 미구현) - const level = equipped ? 0 : 0 - const growth = 0 + const level = progress?.level ?? 0 + const growth = progress?.growth ?? 0 const requireGrowth = symbol.levels?.[0]?.required_count || 0 const remainingSymbols = '-' const remainingMeso = '-' @@ -96,7 +103,7 @@ function SymbolCard({ symbol, equipped }) {