From 3769e3989a9cf249df2c5f9c6f1538ef4652ad5f Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 13 Jun 2025 15:33:02 +0900 Subject: [PATCH 01/29] =?UTF-8?q?style=20:=20=EA=B8=B8=EB=93=9C=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=EC=83=89=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Home.tsx | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 0baa811..6c0e27e 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -178,19 +178,14 @@ const Home = () => {
{/* 길드 검색 */}
-
-
- - 서비스 준비중 - -
-
-
+
-
+
-

길드 검색

+

+ 길드 검색 +

@@ -199,30 +194,24 @@ const Home = () => { placeholder="길드 이름을 입력하세요" value={guildName} onChange={e => setGuildName(e.target.value)} - className="flex-1 px-3 py-2 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500" - disabled + className="flex-1 px-4 py-2.5 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 bg-white" />
-

검색할 길드 목록

+

검색할 길드 목록

-
- - 아르카나 - +
+ 아르카나
-
- - 노비맙단 - +
+ 노비맙단
@@ -230,8 +219,7 @@ const Home = () => {
From e9bd031f391f97e13de4fc296a05cfe7d315a594 Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 13 Jun 2025 15:41:44 +0900 Subject: [PATCH 02/29] =?UTF-8?q?feat=20:=20=EA=B8=B8=EB=93=9C=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=ED=95=A0=20=EA=B8=B8=EB=93=9C=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Home.tsx | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 6c0e27e..a443959 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -26,6 +26,7 @@ const Home = () => { const [characterName, setCharacterName] = useState('') const [guildName, setGuildName] = useState('') + const [guildList, setGuildList] = useState([]) const handleGuestLogin = async () => { await storeLogin('', '', 'guest') @@ -56,6 +57,25 @@ const Home = () => { } } + const addGuildList = (guildName: string) => { + if (guildList.includes(guildName)) { + alert('이미 추가된 길드입니다.') + return + } + if (guildName.trim() === '') { + alert('길드 이름을 입력해주세요.') + return + } + setGuildList(prev => [...prev, guildName]) + setGuildName('') + } + + const handleGuildKeyPress = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + addGuildList(guildName) + } + } + const searchCharacterHandler = async () => { if (characterName.trim() === '') { alert('캐릭터 이름을 입력해주세요.') @@ -194,11 +214,13 @@ const Home = () => { placeholder="길드 이름을 입력하세요" value={guildName} onChange={e => setGuildName(e.target.value)} + onKeyPress={handleGuildKeyPress} className="flex-1 px-4 py-2.5 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 bg-white" /> @@ -207,12 +229,11 @@ const Home = () => {

검색할 길드 목록

-
- 아르카나 -
-
- 노비맙단 -
+ {guildList.map(guild => ( +
+ {guild} +
+ ))}
From 3144d86a6b5d3b1622f992dddb1197867378bb36 Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 13 Jun 2025 16:16:47 +0900 Subject: [PATCH 03/29] =?UTF-8?q?feat=20:=20=EA=B8=B8=EB=93=9C=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=9D=BC=EC=9A=B0?= =?UTF-8?q?=ED=84=B0=20=EC=A7=80=EC=A0=95=20=EB=B0=8F=20=ED=97=A4=EB=8D=94?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 9 +++++++ src/components/common/Header.tsx | 12 ++++----- src/pages/Home.tsx | 43 +++++++++++++++++++++++++++++++- src/pages/SearchGuild.tsx | 3 +++ 4 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 src/pages/SearchGuild.tsx diff --git a/src/App.tsx b/src/App.tsx index b1be2f4..da0e0a9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -15,6 +15,7 @@ import Room from './pages/Room' import { GuildPromotion } from './pages/GuildPromotion' import Notice from './pages/Notice' import { SearchCharacter } from './pages/SearchCharacter' +import { SearchGuild } from './pages/SearchGuild' const router = createBrowserRouter([ { @@ -126,6 +127,14 @@ const router = createBrowserRouter([ ) + }, + { + path: '/searchGuild', + element: ( + + + + ) } ]) diff --git a/src/components/common/Header.tsx b/src/components/common/Header.tsx index 45a36a9..e5d93b8 100644 --- a/src/components/common/Header.tsx +++ b/src/components/common/Header.tsx @@ -46,13 +46,13 @@ function Header() { className="hover:text-blue-600 font-medium transition-all"> 캐릭터검색 - {/* */} + ) : ( <> @@ -140,13 +140,13 @@ function Header() { className="hover:text-blue-600 font-medium transition-all"> 캐릭터검색 - {/* */} + ) : ( <> diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index a443959..e8068cc 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -70,12 +70,33 @@ const Home = () => { setGuildName('') } + const removeGuildList = (guildToRemove: string) => { + setGuildList(prev => prev.filter(guild => guild !== guildToRemove)) + } + const handleGuildKeyPress = (e: React.KeyboardEvent) => { if (e.key === 'Enter') { addGuildList(guildName) } } + const searchGuildHandler = async () => { + if (guildList.length === 0) { + alert('검색할 길드를 추가해주세요.') + return + } + await storeLogin('', '', 'search') + setUserInfo({ + id: 0, + firebaseId: '1', + name: 'search', + email: 'play3step@gmail.com', + ocid: guest.ocid + }) + + nav(`/searchGuild`) + } + const searchCharacterHandler = async () => { if (characterName.trim() === '') { alert('캐릭터 이름을 입력해주세요.') @@ -230,8 +251,27 @@ const Home = () => {

검색할 길드 목록

{guildList.map(guild => ( -
+
{guild} +
))}
@@ -240,6 +280,7 @@ const Home = () => { diff --git a/src/pages/SearchGuild.tsx b/src/pages/SearchGuild.tsx new file mode 100644 index 0000000..c3080da --- /dev/null +++ b/src/pages/SearchGuild.tsx @@ -0,0 +1,3 @@ +export const SearchGuild = () => { + return
SearchGuild
+} From 353dbf9bc0496be51cd5175698e320dc9e9c1fab Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 13 Jun 2025 17:34:06 +0900 Subject: [PATCH 04/29] =?UTF-8?q?style=20:=20=EA=B8=B8=EB=93=9C=20?= =?UTF-8?q?=EC=9B=94=EB=93=9C=20=EC=84=A0=ED=83=9D=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Home.tsx | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index e8068cc..94f2108 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -27,6 +27,24 @@ const Home = () => { const [characterName, setCharacterName] = useState('') const [guildName, setGuildName] = useState('') const [guildList, setGuildList] = useState([]) + const [selectedServer, setSelectedServer] = useState('') + + const servers = [ + { id: '스카니아', name: '스카니아' }, + { id: '베라', name: '베라' }, + { id: '루나', name: '루나' }, + { id: '제니스', name: '제니스' }, + { id: '크로아', name: '크로아' }, + { id: '유니온', name: '유니온' }, + { id: '엘리시움', name: '엘리시움' }, + { id: '이노시스', name: '이노시스' }, + { id: '레드', name: '레드' }, + { id: '오로라', name: '오로라' }, + { id: '아케인', name: '아케인' }, + { id: '노바', name: '노바' }, + { id: '에오스', name: '에오스' }, + { id: '핼리오스', name: '핼리오스' } + ] const handleGuestLogin = async () => { await storeLogin('', '', 'guest') @@ -58,6 +76,10 @@ const Home = () => { } const addGuildList = (guildName: string) => { + if (!selectedServer) { + alert('서버를 선택해주세요.') + return + } if (guildList.includes(guildName)) { alert('이미 추가된 길드입니다.') return @@ -85,6 +107,10 @@ const Home = () => { alert('검색할 길드를 추가해주세요.') return } + if (!selectedServer) { + alert('서버를 선택해주세요.') + return + } await storeLogin('', '', 'search') setUserInfo({ id: 0, @@ -230,6 +256,19 @@ const Home = () => {
+ Date: Fri, 13 Jun 2025 17:49:42 +0900 Subject: [PATCH 05/29] =?UTF-8?q?feat=20:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=97=86=EC=9D=B4=20=EA=B8=B8=EB=93=9C=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/guild/guildController.ts | 12 ++++++++++++ src/pages/Home.tsx | 3 +++ 2 files changed, 15 insertions(+) diff --git a/src/apis/guild/guildController.ts b/src/apis/guild/guildController.ts index c631603..22c60fe 100644 --- a/src/apis/guild/guildController.ts +++ b/src/apis/guild/guildController.ts @@ -48,3 +48,15 @@ export const searchGuild = async (params: Guild) => { ) return guildInfo } + +//로그인 없이 길드 조회 +export const searchGuildWithoutLogin = async ( + guildNames: string[], + worldName: string +) => { + const response = await basicApi.post('/api/none/guilds', { + guildNames, + worldName + }) + return response.data +} diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 94f2108..ed7ad10 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -16,6 +16,7 @@ import { guest } from '../data/guest' import { useState } from 'react' import Button from '../components/common/Button' import { searchCharacterOcid } from '../apis/character/characterController' +import { searchGuildWithoutLogin } from '../apis/guild/guildController' const Home = () => { const { userLogin } = useAuth() @@ -111,6 +112,8 @@ const Home = () => { alert('서버를 선택해주세요.') return } + const guilds = await searchGuildWithoutLogin(guildList, selectedServer) + console.log(guilds) await storeLogin('', '', 'search') setUserInfo({ id: 0, From 610c1c480f9008dc0d5788b5039d411a07f52b3b Mon Sep 17 00:00:00 2001 From: echo Date: Sat, 14 Jun 2025 20:31:52 +0900 Subject: [PATCH 06/29] =?UTF-8?q?feat=20:=20=EA=B8=B8=EB=93=9C=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=ED=83=80=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/guild/guildController.ts | 15 +++++++++------ src/apis/index.ts | 8 ++++++++ src/hooks/search/useSearchGuild.ts | 11 +++++++++++ src/pages/Home.tsx | 4 +--- src/pages/SearchGuild.tsx | 10 ++++++++++ src/types/guild.ts | 14 ++++++++++++-- 6 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 src/hooks/search/useSearchGuild.ts diff --git a/src/apis/guild/guildController.ts b/src/apis/guild/guildController.ts index 22c60fe..cf471f3 100644 --- a/src/apis/guild/guildController.ts +++ b/src/apis/guild/guildController.ts @@ -1,5 +1,5 @@ -import { basicApi, nexonApi } from '..' -import { Guild, SearchGuild } from '../../types/guild' +import { basicApi, nexonApi, publicApi } from '..' +import { Guild, SearchGuild, SearchGuildResponse } from '../../types/guild' //길드 목록 조회 export const fetchGuildList = async () => { @@ -54,9 +54,12 @@ export const searchGuildWithoutLogin = async ( guildNames: string[], worldName: string ) => { - const response = await basicApi.post('/api/none/guilds', { - guildNames, - worldName - }) + const response = await publicApi.post( + 'api/v1/public/guilds', + { + guildNames, + worldName + } + ) return response.data } diff --git a/src/apis/index.ts b/src/apis/index.ts index b24ae6a..302503d 100644 --- a/src/apis/index.ts +++ b/src/apis/index.ts @@ -14,6 +14,14 @@ export const basicApi = axios.create({ } }) +export const publicApi = axios.create({ + baseURL: API_KEY, + timeout: DEFAULT_TIMEOUT, + headers: { + 'Content-Type': 'application/json;charset=utf-8' + } +}) + basicApi.interceptors.request.use(config => { const token = useAuthStore.getState().token if (token) { diff --git a/src/hooks/search/useSearchGuild.ts b/src/hooks/search/useSearchGuild.ts new file mode 100644 index 0000000..f017e74 --- /dev/null +++ b/src/hooks/search/useSearchGuild.ts @@ -0,0 +1,11 @@ +import { useQuery } from '@tanstack/react-query' +import { searchGuildWithoutLogin } from '../../apis/guild/guildController' + +export const useSearchGuild = () => { + const { data: guilds, isLoading } = useQuery({ + queryKey: ['guilds'], + queryFn: () => searchGuildWithoutLogin(['리더'], '스카니아') + }) + + return { guilds, isLoading } +} diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index ed7ad10..4f3a5ea 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -16,7 +16,6 @@ import { guest } from '../data/guest' import { useState } from 'react' import Button from '../components/common/Button' import { searchCharacterOcid } from '../apis/character/characterController' -import { searchGuildWithoutLogin } from '../apis/guild/guildController' const Home = () => { const { userLogin } = useAuth() @@ -112,8 +111,7 @@ const Home = () => { alert('서버를 선택해주세요.') return } - const guilds = await searchGuildWithoutLogin(guildList, selectedServer) - console.log(guilds) + await storeLogin('', '', 'search') setUserInfo({ id: 0, diff --git a/src/pages/SearchGuild.tsx b/src/pages/SearchGuild.tsx index c3080da..7a77a69 100644 --- a/src/pages/SearchGuild.tsx +++ b/src/pages/SearchGuild.tsx @@ -1,3 +1,13 @@ +import { useSearchGuild } from '../hooks/search/useSearchGuild' + export const SearchGuild = () => { + const { guilds, isLoading } = useSearchGuild() + + console.log(guilds) + + if (isLoading) { + return
Loading...
+ } + return
SearchGuild
} diff --git a/src/types/guild.ts b/src/types/guild.ts index ca71e13..d9afc25 100644 --- a/src/types/guild.ts +++ b/src/types/guild.ts @@ -46,7 +46,7 @@ export interface RecordedMembers { } export interface Member { - id: number + id?: number imagePath: string job: string level: string @@ -59,7 +59,6 @@ export interface Member { level: string job: string imagePath: string - description: string } } @@ -74,3 +73,14 @@ export interface DetectResult { toAdd: string[] toRemove: string[] } + +export interface SearchGuildResponse { + guilds: GuildInfo[] +} + +export interface GuildInfo { + worldName: string + guildName: string + guildMasterName: string + guildMember: Member[] +} From 98c11467e0880472abab4bce0c11f5161b8b374f Mon Sep 17 00:00:00 2001 From: echo Date: Sat, 14 Jun 2025 20:48:35 +0900 Subject: [PATCH 07/29] =?UTF-8?q?feat=20:=20=EA=B8=B8=EB=93=9C=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20params=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/search/useSearchGuild.ts | 40 +++++++++++++++++++++++-- src/pages/Home.tsx | 47 ++++++++++++++---------------- src/pages/SearchGuild.tsx | 6 +--- 3 files changed, 60 insertions(+), 33 deletions(-) diff --git a/src/hooks/search/useSearchGuild.ts b/src/hooks/search/useSearchGuild.ts index f017e74..ae27ac6 100644 --- a/src/hooks/search/useSearchGuild.ts +++ b/src/hooks/search/useSearchGuild.ts @@ -1,11 +1,45 @@ -import { useQuery } from '@tanstack/react-query' import { searchGuildWithoutLogin } from '../../apis/guild/guildController' +import { useState } from 'react' + +import { useQuery } from '@tanstack/react-query' +import { useSearchParams } from 'react-router-dom' export const useSearchGuild = () => { + const [guildList, setGuildList] = useState([]) + const [selectedServer, setSelectedServer] = useState('') + + const [searchParams, setSearchParams] = useSearchParams() + const { data: guilds, isLoading } = useQuery({ queryKey: ['guilds'], - queryFn: () => searchGuildWithoutLogin(['리더'], '스카니아') + queryFn: () => searchGuildWithoutLogin(guildList, selectedServer) }) - return { guilds, isLoading } + const searchGuildHandler = async () => { + if (guildList.length === 0) { + alert('검색할 길드를 추가해주세요.') + return + } + + if (!selectedServer) { + alert('서버를 선택해주세요.') + return + } + + const newSearchParams = new URLSearchParams(searchParams) + newSearchParams.set('guildList', guildList.join(',')) + newSearchParams.set('server', selectedServer) + setSearchParams(newSearchParams) + } + + return { + searchGuildHandler, + guildList, + setGuildList, + selectedServer, + setSelectedServer, + + guilds, + isLoading + } } diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 4f3a5ea..36f2ee3 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -16,6 +16,7 @@ import { guest } from '../data/guest' import { useState } from 'react' import Button from '../components/common/Button' import { searchCharacterOcid } from '../apis/character/characterController' +import { useSearchGuild } from '../hooks/search/useSearchGuild' const Home = () => { const { userLogin } = useAuth() @@ -26,8 +27,14 @@ const Home = () => { const [characterName, setCharacterName] = useState('') const [guildName, setGuildName] = useState('') - const [guildList, setGuildList] = useState([]) - const [selectedServer, setSelectedServer] = useState('') + + const { + selectedServer, + setSelectedServer, + guildList, + setGuildList, + searchGuildHandler + } = useSearchGuild() const servers = [ { id: '스카니아', name: '스카니아' }, @@ -102,28 +109,6 @@ const Home = () => { } } - const searchGuildHandler = async () => { - if (guildList.length === 0) { - alert('검색할 길드를 추가해주세요.') - return - } - if (!selectedServer) { - alert('서버를 선택해주세요.') - return - } - - await storeLogin('', '', 'search') - setUserInfo({ - id: 0, - firebaseId: '1', - name: 'search', - email: 'play3step@gmail.com', - ocid: guest.ocid - }) - - nav(`/searchGuild`) - } - const searchCharacterHandler = async () => { if (characterName.trim() === '') { alert('캐릭터 이름을 입력해주세요.') @@ -148,6 +133,18 @@ const Home = () => { }) nav(`/searchCharacter`) } + const onSearchGuild = async () => { + await storeLogin('', '', 'search') + setUserInfo({ + id: 0, + firebaseId: '1', + name: 'search', + email: 'play3step@gmail.com', + ocid: guest.ocid + }) + nav(`/searchGuild`) + searchGuildHandler() + } const recentNotices = [ { @@ -320,7 +317,7 @@ const Home = () => { diff --git a/src/pages/SearchGuild.tsx b/src/pages/SearchGuild.tsx index 7a77a69..d54c8d9 100644 --- a/src/pages/SearchGuild.tsx +++ b/src/pages/SearchGuild.tsx @@ -1,13 +1,9 @@ import { useSearchGuild } from '../hooks/search/useSearchGuild' export const SearchGuild = () => { - const { guilds, isLoading } = useSearchGuild() + const { guilds } = useSearchGuild() console.log(guilds) - if (isLoading) { - return
Loading...
- } - return
SearchGuild
} From b3eeb20df3a574b166a903222fcd1871e4409c96 Mon Sep 17 00:00:00 2001 From: echo Date: Sat, 14 Jun 2025 21:39:03 +0900 Subject: [PATCH 08/29] =?UTF-8?q?refactor=20:=20=EA=B8=B8=EB=93=9C=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81=20?= =?UTF-8?q?=EB=B0=8F=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=97=86=EC=9D=84=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EA=B2=80=EC=83=89=20=EC=B0=BD=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/Header.tsx | 8 ++- src/data/worlds.ts | 17 +++++ src/hooks/search/useSearchGuild.ts | 36 +++++++++- src/pages/Home.tsx | 54 ++------------- src/pages/SearchGuild.tsx | 106 ++++++++++++++++++++++++++++- 5 files changed, 166 insertions(+), 55 deletions(-) diff --git a/src/components/common/Header.tsx b/src/components/common/Header.tsx index e5d93b8..fb3112f 100644 --- a/src/components/common/Header.tsx +++ b/src/components/common/Header.tsx @@ -23,7 +23,9 @@ function Header() {
- {userType === 'search' ? ( + {userType === 'search' || userType === undefined ? ( <> +
+ +
+

검색할 길드 목록

+
+ {guildList.map(guild => ( +
+ {guild} + +
+ ))} +
+
+ + +
+
+
+ )} +
+ ) } From e7146cec5e1cc18be4b69056ad1aaf7459274c4f Mon Sep 17 00:00:00 2001 From: echo Date: Sat, 14 Jun 2025 22:00:20 +0900 Subject: [PATCH 09/29] =?UTF-8?q?fix=20:=20=EB=94=94=ED=8F=B4=ED=8A=B8=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=20=EC=A0=95=EB=B3=B4=20=EB=B0=8F=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Home.tsx | 28 +++------------------------- src/store/authStore.ts | 4 ++-- src/store/userStore.ts | 9 ++++++++- 3 files changed, 13 insertions(+), 28 deletions(-) diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 159c385..4c59a99 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -12,7 +12,6 @@ import { import Logo from '../assets/logo.png' import GoogleLogo from '../assets/gogle.svg' import { useUserStore } from '../store/userStore' -import { guest } from '../data/guest' import { useState } from 'react' import Button from '../components/common/Button' import { searchCharacterOcid } from '../apis/character/characterController' @@ -22,7 +21,7 @@ import { servers } from '../data/worlds' const Home = () => { const { userLogin } = useAuth() const { storeLogin } = useAuthStore() - const { setUserInfo } = useUserStore() + const { setUserInfo, updateUserInfo } = useUserStore() const nav = useNavigate() const KAKAO_CHAT_LINK = 'https://open.kakao.com/o/s4tfG2Ah' @@ -42,13 +41,7 @@ const Home = () => { const handleGuestLogin = async () => { await storeLogin('', '', 'guest') - setUserInfo({ - id: 0, - firebaseId: '1', - name: 'guest', - email: 'play3step@gmail.com', - ocid: guest.ocid - }) + nav('/character') } @@ -83,25 +76,10 @@ const Home = () => { } await storeLogin('', '', 'search') - - setUserInfo({ - id: 0, - firebaseId: '1', - name: characterName.trim(), - email: 'play3step@gmail.com', - ocid: ocid - }) + updateUserInfo({ ocid }) nav(`/searchCharacter`) } const onSearchGuild = async () => { - await storeLogin('', '', 'search') - setUserInfo({ - id: 0, - firebaseId: '1', - name: 'search', - email: 'play3step@gmail.com', - ocid: guest.ocid - }) nav(`/searchGuild`) searchGuildHandler() } diff --git a/src/store/authStore.ts b/src/store/authStore.ts index bd1c450..149e9c0 100644 --- a/src/store/authStore.ts +++ b/src/store/authStore.ts @@ -15,11 +15,11 @@ export const useAuthStore = create(set => ({ token: null, uid: null, isLoggedIn: false, - userType: 'guest', + userType: 'search', storeLogin: (token: string, uid: string, userType: UserType) => { set({ token, uid, isLoggedIn: true, userType }) }, storeLogout: () => { - set({ token: null, uid: null, isLoggedIn: false, userType: 'guest' }) + set({ token: null, uid: null, isLoggedIn: false, userType: 'search' }) } })) diff --git a/src/store/userStore.ts b/src/store/userStore.ts index 4d490c7..6bf170e 100644 --- a/src/store/userStore.ts +++ b/src/store/userStore.ts @@ -1,5 +1,6 @@ import { create } from 'zustand' import { User } from '../types/auth' +import { guest } from '../data/guest' interface UserState { userInfo: User | null @@ -13,7 +14,13 @@ interface UserState { } export const useUserStore = create(set => ({ - userInfo: null, + userInfo: { + id: 0, + firebaseId: '1', + name: 'search', + email: 'play3step@gmail.com', + ocid: guest.ocid + }, userName: null, setUserInfo: info => set({ userInfo: info }), From 95d03cacd1a54728360363ecc5dbcbf2aad421f0 Mon Sep 17 00:00:00 2001 From: echo Date: Sun, 15 Jun 2025 12:04:47 +0900 Subject: [PATCH 10/29] =?UTF-8?q?feat=20:=20params=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B8=B8=EB=93=9C=20=EA=B2=80=EC=83=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/guild/guildController.ts | 4 ++-- src/hooks/search/useSearchGuild.ts | 9 +++++++-- src/pages/SearchGuild.tsx | 15 +++++++++++++-- src/types/guild.ts | 4 ---- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/apis/guild/guildController.ts b/src/apis/guild/guildController.ts index cf471f3..fccd49e 100644 --- a/src/apis/guild/guildController.ts +++ b/src/apis/guild/guildController.ts @@ -54,8 +54,8 @@ export const searchGuildWithoutLogin = async ( guildNames: string[], worldName: string ) => { - const response = await publicApi.post( - 'api/v1/public/guilds', + const response = await publicApi.post( + '/api/v1/public/guilds/async', { guildNames, worldName diff --git a/src/hooks/search/useSearchGuild.ts b/src/hooks/search/useSearchGuild.ts index 11dfd54..deceaa5 100644 --- a/src/hooks/search/useSearchGuild.ts +++ b/src/hooks/search/useSearchGuild.ts @@ -10,9 +10,14 @@ export const useSearchGuild = () => { const [guildName, setGuildName] = useState('') const [searchParams, setSearchParams] = useSearchParams() + const params = new URLSearchParams(searchParams) + + const serachGuildList = params.get('guildList')?.split(',') || [] + const serachServer = params.get('server') || '' + const { data: guilds, isLoading } = useQuery({ - queryKey: ['guilds'], - queryFn: () => searchGuildWithoutLogin(guildList, selectedServer) + queryKey: ['guilds', serachGuildList, serachServer], + queryFn: () => searchGuildWithoutLogin(serachGuildList, serachServer) }) const addGuildList = (guildName: string) => { diff --git a/src/pages/SearchGuild.tsx b/src/pages/SearchGuild.tsx index da62297..b6e9f6b 100644 --- a/src/pages/SearchGuild.tsx +++ b/src/pages/SearchGuild.tsx @@ -15,14 +15,17 @@ export const SearchGuild = () => { addGuildList, removeGuildList, guildList, - searchGuildHandler + searchGuildHandler, + isLoading } = useSearchGuild() + if (isLoading) return
Loading...
+ console.log(guilds) return (
- {guilds && guilds.guilds.length === 0 && ( + {guilds?.length === 0 ? (
@@ -105,6 +108,14 @@ export const SearchGuild = () => {
+ ) : ( +
+ {guilds?.map(guild => ( +
+ {guild.worldName} {guild.guildName} +
+ ))} +
)}
) diff --git a/src/types/guild.ts b/src/types/guild.ts index d9afc25..d551a97 100644 --- a/src/types/guild.ts +++ b/src/types/guild.ts @@ -75,10 +75,6 @@ export interface DetectResult { } export interface SearchGuildResponse { - guilds: GuildInfo[] -} - -export interface GuildInfo { worldName: string guildName: string guildMasterName: string From a84bca19c00855f3a212470c04f78605ffaf4ca8 Mon Sep 17 00:00:00 2001 From: echo Date: Sun, 15 Jun 2025 21:58:27 +0900 Subject: [PATCH 11/29] =?UTF-8?q?feat=20:=20=EA=B8=B8=EB=93=9C=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EA=B2=B0=EA=B3=BC=20=EC=B6=9C=EB=A0=A5=20=EB=B0=8F?= =?UTF-8?q?=20=EC=97=91=EC=85=98=20=EB=B2=84=ED=8A=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/guild/guildController.ts | 14 +- src/components/guild/ActionBtnList.tsx | 181 ++++++++++++++----------- src/hooks/search/useSearchGuild.ts | 6 +- src/pages/SearchGuild.tsx | 72 ++++++++-- 4 files changed, 179 insertions(+), 94 deletions(-) diff --git a/src/apis/guild/guildController.ts b/src/apis/guild/guildController.ts index fccd49e..621569d 100644 --- a/src/apis/guild/guildController.ts +++ b/src/apis/guild/guildController.ts @@ -55,7 +55,7 @@ export const searchGuildWithoutLogin = async ( worldName: string ) => { const response = await publicApi.post( - '/api/v1/public/guilds/async', + '/api/v1/public/guilds/async/test', { guildNames, worldName @@ -63,3 +63,15 @@ export const searchGuildWithoutLogin = async ( ) return response.data } + +//로그인 없이 길드 본/부캐 조회 + +export const searchGuildMemberWithoutLogin = async (members: string[]) => { + const response = await publicApi.post( + '/api/v1/public/guilds/member/async', + { + members + } + ) + return response.data +} diff --git a/src/components/guild/ActionBtnList.tsx b/src/components/guild/ActionBtnList.tsx index cb7cb57..dd20660 100644 --- a/src/components/guild/ActionBtnList.tsx +++ b/src/components/guild/ActionBtnList.tsx @@ -11,9 +11,9 @@ import { } from 'react-icons/io5' interface Props { - showModal: (name: ModalType) => void + showModal?: (name: ModalType) => void guildList: Guild[] - handleDetect: () => void + handleDetect?: () => void refreshMember?: (guildId: number) => void } @@ -87,104 +87,125 @@ export const ActionBtnList = ({ return (
- -
-
- ⚠️ 관리방 생성은 길드 마스터만 가능합니다. -
마스터가 아니라면, 마스터를 그룹에 초대해 생성해주세요. -
-
+ {showModal && ( + <> + +
+
+ ⚠️ 관리방 생성은 길드 마스터만 가능합니다. +
마스터가 아니라면, 마스터를 그룹에 초대해 생성해주세요. +
+
+ + )}
{guildList.length > 0 && ( <>
-
- + + {isOpen && ( +
+ {guildList.map(guild => ( + + ))} +
)} - - +
+ ) : ( +
+ {guildList.map(guild => ( + + ))} +
+ )} - {isOpen && ( -
- {guildList.map(guild => ( + {handleDetect && showModal && ( +
+
+ { - ))} + } + +
+
+ 캐릭터의 본/부캐 정보를 새로고침합니다 +
+
- )} -
-
-
- { +
- } - -
-
- 캐릭터의 본/부캐 정보를 새로고침합니다 -
-
-
- -
- -
-
- 기록된 길드원 정보를 게임 내 정보와 비교합니다. +
+
+ 기록된 길드원 정보를 게임 내 정보와 비교합니다. +
-
+ )}
)} diff --git a/src/hooks/search/useSearchGuild.ts b/src/hooks/search/useSearchGuild.ts index deceaa5..a777785 100644 --- a/src/hooks/search/useSearchGuild.ts +++ b/src/hooks/search/useSearchGuild.ts @@ -15,8 +15,8 @@ export const useSearchGuild = () => { const serachGuildList = params.get('guildList')?.split(',') || [] const serachServer = params.get('server') || '' - const { data: guilds, isLoading } = useQuery({ - queryKey: ['guilds', serachGuildList, serachServer], + const { data: guildsInfo, isLoading } = useQuery({ + queryKey: ['guildsInfo', serachGuildList, serachServer], queryFn: () => searchGuildWithoutLogin(serachGuildList, serachServer) }) @@ -71,7 +71,7 @@ export const useSearchGuild = () => { setSelectedServer, guildName, setGuildName, - guilds, + guildsInfo, isLoading, addGuildList, removeGuildList, diff --git a/src/pages/SearchGuild.tsx b/src/pages/SearchGuild.tsx index b6e9f6b..74e9929 100644 --- a/src/pages/SearchGuild.tsx +++ b/src/pages/SearchGuild.tsx @@ -3,10 +3,15 @@ import Button from '../components/common/Button' import { useSearchGuild } from '../hooks/search/useSearchGuild' import { servers } from '../data/worlds' +import { IoArrowBack } from 'react-icons/io5' +import { MemberContainer } from '../components/guild/MemberContainer' +import { Empty } from '../components/common/Empty' +import { ActionBtnList } from '../components/guild/ActionBtnList' +import { Guild } from '../types/guild' export const SearchGuild = () => { const { - guilds, + guildsInfo, selectedServer, setSelectedServer, guildName, @@ -19,13 +24,11 @@ export const SearchGuild = () => { isLoading } = useSearchGuild() - if (isLoading) return
Loading...
- - console.log(guilds) + console.log(guildsInfo) return (
- {guilds?.length === 0 ? ( + {guildsInfo?.length === 0 ? (
@@ -109,12 +112,61 @@ export const SearchGuild = () => {
) : ( -
- {guilds?.map(guild => ( -
- {guild.worldName} {guild.guildName} +
+
+ +
+

길드 관리

+

길드원 정보 관리

- ))} +
+ +
+
+
+ ({ + worldName: v.worldName, + guildName: v.guildName + })) as Guild[]) || [] + } + /> + {/* {guildList.length > 0 && } */} +
+
+
+
+ {isLoading && ( +
+
+

+ 캐릭터 정보를 불러오는 중... +

+
+ )} + {guildsInfo && guildsInfo.length > 0 && ( + {}} + searchCharacter={''} + setSearchCharacter={() => {}} + /> + )} + {guildsInfo && guildsInfo.length === 0 && ( + + )} +
+
+
)}
From 683a6158f5a9509d5ef3b2d172ced74d5e04d53c Mon Sep 17 00:00:00 2001 From: echo Date: Sun, 15 Jun 2025 23:02:58 +0900 Subject: [PATCH 12/29] =?UTF-8?q?fix=20:=20=EB=B3=B8=EC=BA=90=20=EB=B6=80?= =?UTF-8?q?=EC=BA=90=20=EB=B9=84=EA=B5=90=20id=20=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=8B=89=EB=84=A4=EC=9E=84=EC=9C=BC=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/guild/ActionBtnList.tsx | 2 +- src/components/guild/MemberContainer.tsx | 21 +++++++++++++------- src/hooks/search/useSearchGuild.ts | 8 +++++++- src/pages/Room.tsx | 2 +- src/pages/SearchGuild.tsx | 25 +++++++++++++++++------- src/types/guild.ts | 2 +- 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/components/guild/ActionBtnList.tsx b/src/components/guild/ActionBtnList.tsx index dd20660..c8bb6fb 100644 --- a/src/components/guild/ActionBtnList.tsx +++ b/src/components/guild/ActionBtnList.tsx @@ -152,7 +152,7 @@ export const ActionBtnList = ({ onClick={() => { handleSwitch(guild.guildName || '') }} - className="w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 hover:text-blue-600 whitespace-nowrap text-ellipsis"> + className="w-full border border-gray-200 rounded-lg text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 hover:text-blue-600 whitespace-nowrap text-ellipsis"> {guild.guildName} ))} diff --git a/src/components/guild/MemberContainer.tsx b/src/components/guild/MemberContainer.tsx index cdbf05a..78d9250 100644 --- a/src/components/guild/MemberContainer.tsx +++ b/src/components/guild/MemberContainer.tsx @@ -63,7 +63,7 @@ export const MemberContainer = ({ member.type === '부캐' && allMembers?.find(m => m.memberDetailResponse?.find( - m => m.id === member.mainCharacterInfo?.id + m => m.name === member.mainCharacterInfo?.name ) ) && member.name.toLowerCase().includes(searchCharacter?.toLowerCase() || '') @@ -76,7 +76,9 @@ export const MemberContainer = ({ return ( member.type === '부캐' && !allMembers?.find(m => - m.memberDetailResponse?.find(m => m.id === member.mainCharacterInfo?.id) + m.memberDetailResponse?.find( + m => m.name === member.mainCharacterInfo?.name + ) ) ) }) @@ -235,7 +237,7 @@ export const MemberContainer = ({ ?.flatMap(g => g.memberDetailResponse) .find( m => - m?.id === member.mainCharacterInfo!.id && + m?.name === member.mainCharacterInfo!.name && m.type === '본캐' ) @@ -272,7 +274,8 @@ export const MemberContainer = ({ allMembers?.find(m => m.memberDetailResponse?.find( m => - m.id === member.mainCharacterInfo?.id + m.name === + member.mainCharacterInfo?.name ) ) ? 'bg-yellow-100 text-yellow-700' @@ -283,18 +286,22 @@ export const MemberContainer = ({ : member.type === '부캐' && allMembers?.find(m => m.memberDetailResponse?.find( - m => m.id === member.mainCharacterInfo?.id + m => + m.name === + member.mainCharacterInfo?.name ) ) ? '부캐' - : '외부 부캐'} + : member.mainCharacterInfo === null + ? '' + : '외부 부캐'} )}
{member.type === '부캐' && !allMembers?.find(m => m.memberDetailResponse?.find( - m => m.id === member.mainCharacterInfo?.id + m => m.name === member.mainCharacterInfo?.name ) ) && ( diff --git a/src/hooks/search/useSearchGuild.ts b/src/hooks/search/useSearchGuild.ts index a777785..45129f3 100644 --- a/src/hooks/search/useSearchGuild.ts +++ b/src/hooks/search/useSearchGuild.ts @@ -14,6 +14,7 @@ export const useSearchGuild = () => { const serachGuildList = params.get('guildList')?.split(',') || [] const serachServer = params.get('server') || '' + const selectedGuild = params.get('guild') || '' const { data: guildsInfo, isLoading } = useQuery({ queryKey: ['guildsInfo', serachGuildList, serachServer], @@ -63,6 +64,10 @@ export const useSearchGuild = () => { setSearchParams(newSearchParams) } + const selectedGuildMember = guildsInfo?.find( + guild => guild.guildName === selectedGuild + ) + return { searchGuildHandler, guildList, @@ -75,6 +80,7 @@ export const useSearchGuild = () => { isLoading, addGuildList, removeGuildList, - handleGuildKeyPress + handleGuildKeyPress, + selectedGuildMember } } diff --git a/src/pages/Room.tsx b/src/pages/Room.tsx index e19004d..a2df814 100644 --- a/src/pages/Room.tsx +++ b/src/pages/Room.tsx @@ -144,7 +144,7 @@ const Room = () => { setSearchCharacter={handleSearchCharacter} onDeleteGuild={ selectMember?.guildId - ? () => deleteGuild(selectMember.guildId) + ? () => deleteGuild(selectMember.guildId as number) : undefined } /> diff --git a/src/pages/SearchGuild.tsx b/src/pages/SearchGuild.tsx index 74e9929..57550fb 100644 --- a/src/pages/SearchGuild.tsx +++ b/src/pages/SearchGuild.tsx @@ -8,6 +8,7 @@ import { MemberContainer } from '../components/guild/MemberContainer' import { Empty } from '../components/common/Empty' import { ActionBtnList } from '../components/guild/ActionBtnList' import { Guild } from '../types/guild' +import { useState } from 'react' export const SearchGuild = () => { const { @@ -21,9 +22,15 @@ export const SearchGuild = () => { removeGuildList, guildList, searchGuildHandler, - isLoading + isLoading, + selectedGuildMember } = useSearchGuild() + const [searchCharacter, setSearchCharacter] = useState('') + + const handleSearchCharacter = (value: string) => { + setSearchCharacter(value) + } console.log(guildsInfo) return ( @@ -152,13 +159,17 @@ export const SearchGuild = () => { )} {guildsInfo && guildsInfo.length > 0 && ( ({ + guildName: v.guildName, + guildMasterName: v.guildMasterName, + memberDetailResponse: v.guildMember + }))} + masterName={selectedGuildMember?.guildMasterName} + guildName={selectedGuildMember?.guildName} onSelect={() => {}} - searchCharacter={''} - setSearchCharacter={() => {}} + searchCharacter={searchCharacter} + setSearchCharacter={handleSearchCharacter} /> )} {guildsInfo && guildsInfo.length === 0 && ( diff --git a/src/types/guild.ts b/src/types/guild.ts index d551a97..6b260e8 100644 --- a/src/types/guild.ts +++ b/src/types/guild.ts @@ -33,7 +33,7 @@ export interface SearchGuild { } export interface NexonMembers { - guildId: number + guildId?: number guildName: string guildMasterName?: string memberDetailResponse?: Member[] From b00aa74901b261c0063d5b3b5961482da5f35c41 Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 16 Jun 2025 00:18:13 +0900 Subject: [PATCH 13/29] =?UTF-8?q?feat=20:=20=EA=B8=B8=EB=93=9C=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EA=B2=B0=EA=B3=BC=20=ED=9B=84=20=EB=B3=B8=EC=BA=90?= =?UTF-8?q?/=EB=B6=80=EC=BA=90=20=EC=A0=95=EB=B3=B4=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/guild/guildController.ts | 9 +++- src/components/guild/ActionBtnList.tsx | 11 ++++- src/hooks/search/useSearchGuild.ts | 59 ++++++++++++++++++++++++-- src/pages/SearchGuild.tsx | 51 +++++++++++----------- src/types/guild.ts | 12 ++++++ 5 files changed, 110 insertions(+), 32 deletions(-) diff --git a/src/apis/guild/guildController.ts b/src/apis/guild/guildController.ts index 621569d..7b2213b 100644 --- a/src/apis/guild/guildController.ts +++ b/src/apis/guild/guildController.ts @@ -1,5 +1,10 @@ import { basicApi, nexonApi, publicApi } from '..' -import { Guild, SearchGuild, SearchGuildResponse } from '../../types/guild' +import { + Guild, + SearchGuild, + SearchGuildMemberResponse, + SearchGuildResponse +} from '../../types/guild' //길드 목록 조회 export const fetchGuildList = async () => { @@ -67,7 +72,7 @@ export const searchGuildWithoutLogin = async ( //로그인 없이 길드 본/부캐 조회 export const searchGuildMemberWithoutLogin = async (members: string[]) => { - const response = await publicApi.post( + const response = await publicApi.post( '/api/v1/public/guilds/member/async', { members diff --git a/src/components/guild/ActionBtnList.tsx b/src/components/guild/ActionBtnList.tsx index c8bb6fb..455d111 100644 --- a/src/components/guild/ActionBtnList.tsx +++ b/src/components/guild/ActionBtnList.tsx @@ -15,13 +15,15 @@ interface Props { guildList: Guild[] handleDetect?: () => void refreshMember?: (guildId: number) => void + mainCharacterInfoSearchHandler?: () => void } export const ActionBtnList = ({ showModal, guildList, handleDetect, - refreshMember + refreshMember, + mainCharacterInfoSearchHandler }: Props) => { const [searchParams, setSearchParams] = useSearchParams() const [selectedGuild, setSelectedGuild] = useState(null) @@ -156,6 +158,13 @@ export const ActionBtnList = ({ {guild.guildName} ))} +
)} diff --git a/src/hooks/search/useSearchGuild.ts b/src/hooks/search/useSearchGuild.ts index 45129f3..411ff95 100644 --- a/src/hooks/search/useSearchGuild.ts +++ b/src/hooks/search/useSearchGuild.ts @@ -1,14 +1,19 @@ -import { searchGuildWithoutLogin } from '../../apis/guild/guildController' +import { + searchGuildMemberWithoutLogin, + searchGuildWithoutLogin +} from '../../apis/guild/guildController' import { useState } from 'react' -import { useQuery } from '@tanstack/react-query' +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { useSearchParams } from 'react-router-dom' +import { SearchGuildResponse } from '../../types/guild' export const useSearchGuild = () => { const [guildList, setGuildList] = useState([]) const [selectedServer, setSelectedServer] = useState('') const [guildName, setGuildName] = useState('') const [searchParams, setSearchParams] = useSearchParams() + const [isUpdating, setIsUpdating] = useState(false) const params = new URLSearchParams(searchParams) @@ -16,11 +21,57 @@ export const useSearchGuild = () => { const serachServer = params.get('server') || '' const selectedGuild = params.get('guild') || '' + const queryClient = useQueryClient() + const { data: guildsInfo, isLoading } = useQuery({ queryKey: ['guildsInfo', serachGuildList, serachServer], queryFn: () => searchGuildWithoutLogin(serachGuildList, serachServer) }) + const mainCharacterInfoSearchMutation = useMutation({ + mutationFn: (members: string[]) => searchGuildMemberWithoutLogin(members) + }) + + const mainCharacterInfoSearchHandler = async () => { + if (!guildsInfo) return + setIsUpdating(true) + + try { + const allMemberNames = guildsInfo + .map(guild => guild.guildMember.map(member => member.name)) + .flat() + + const response = + await mainCharacterInfoSearchMutation.mutateAsync(allMemberNames) + + queryClient.setQueryData( + ['guildsInfo', serachGuildList, serachServer], + (oldData: SearchGuildResponse[]) => { + if (!oldData) return oldData + + return oldData.map(guild => ({ + ...guild, + guildMember: guild.guildMember.map(member => { + const match = response.find(res => res.memberName === member.name) + const matchedMember = match?.mainCharacterInfo + + return { + ...member, + type: match?.type ?? member.type, + mainCharacterInfo: matchedMember ?? member.mainCharacterInfo + } + }) + })) + } + ) + } catch (error) { + console.error('메인 캐릭터 정보 조회 중 오류 발생:', error) + alert('메인 캐릭터 정보 조회 중 오류가 발생했습니다.') + } finally { + setIsUpdating(false) + } + } + const addGuildList = (guildName: string) => { if (!selectedServer) { alert('서버를 선택해주세요.') @@ -78,9 +129,11 @@ export const useSearchGuild = () => { setGuildName, guildsInfo, isLoading, + isUpdating, addGuildList, removeGuildList, handleGuildKeyPress, - selectedGuildMember + selectedGuildMember, + mainCharacterInfoSearchHandler } } diff --git a/src/pages/SearchGuild.tsx b/src/pages/SearchGuild.tsx index 57550fb..60e6270 100644 --- a/src/pages/SearchGuild.tsx +++ b/src/pages/SearchGuild.tsx @@ -3,7 +3,6 @@ import Button from '../components/common/Button' import { useSearchGuild } from '../hooks/search/useSearchGuild' import { servers } from '../data/worlds' -import { IoArrowBack } from 'react-icons/io5' import { MemberContainer } from '../components/guild/MemberContainer' import { Empty } from '../components/common/Empty' import { ActionBtnList } from '../components/guild/ActionBtnList' @@ -23,7 +22,9 @@ export const SearchGuild = () => { guildList, searchGuildHandler, isLoading, - selectedGuildMember + selectedGuildMember, + mainCharacterInfoSearchHandler, + isUpdating } = useSearchGuild() const [searchCharacter, setSearchCharacter] = useState('') @@ -31,7 +32,6 @@ export const SearchGuild = () => { const handleSearchCharacter = (value: string) => { setSearchCharacter(value) } - console.log(guildsInfo) return (
@@ -121,12 +121,6 @@ export const SearchGuild = () => { ) : (
-

길드 관리

길드원 정보 관리

@@ -143,13 +137,15 @@ export const SearchGuild = () => { guildName: v.guildName })) as Guild[]) || [] } + mainCharacterInfoSearchHandler={ + mainCharacterInfoSearchHandler + } /> - {/* {guildList.length > 0 && } */}
- {isLoading && ( + {(isLoading || isUpdating) && (

@@ -157,21 +153,24 @@ export const SearchGuild = () => {

)} - {guildsInfo && guildsInfo.length > 0 && ( - ({ - guildName: v.guildName, - guildMasterName: v.guildMasterName, - memberDetailResponse: v.guildMember - }))} - masterName={selectedGuildMember?.guildMasterName} - guildName={selectedGuildMember?.guildName} - onSelect={() => {}} - searchCharacter={searchCharacter} - setSearchCharacter={handleSearchCharacter} - /> - )} + {guildsInfo && + guildsInfo.length > 0 && + !isLoading && + !isUpdating && ( + ({ + guildName: v.guildName, + guildMasterName: v.guildMasterName, + memberDetailResponse: v.guildMember + }))} + masterName={selectedGuildMember?.guildMasterName} + guildName={selectedGuildMember?.guildName} + onSelect={() => {}} + searchCharacter={searchCharacter} + setSearchCharacter={handleSearchCharacter} + /> + )} {guildsInfo && guildsInfo.length === 0 && ( )} diff --git a/src/types/guild.ts b/src/types/guild.ts index 6b260e8..fc11312 100644 --- a/src/types/guild.ts +++ b/src/types/guild.ts @@ -80,3 +80,15 @@ export interface SearchGuildResponse { guildMasterName: string guildMember: Member[] } + +export interface SearchGuildMemberResponse { + memberName: string + type: string + mainCharacterInfo: { + name: string + level: string + job: string + imagePath: string + gender: string + } +} From 3ecce5b9f236416d02c086651a14de29304074af Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 16 Jun 2025 12:31:33 +0900 Subject: [PATCH 14/29] =?UTF-8?q?feat=20:=20=EB=8B=A4=EB=A5=B8=20=EA=B8=B8?= =?UTF-8?q?=EB=93=9C=20=EA=B2=80=EC=83=89=20=EB=B0=8F=20=EA=B8=B8=EB=93=9C?= =?UTF-8?q?=20=EA=B2=80=EC=83=89=20=EC=98=A4=EB=A5=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/search/useSearchGuild.ts | 21 ++++++++++++++++++--- src/pages/SearchGuild.tsx | 23 +++++++++++++++++++++-- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/hooks/search/useSearchGuild.ts b/src/hooks/search/useSearchGuild.ts index 411ff95..8519a7c 100644 --- a/src/hooks/search/useSearchGuild.ts +++ b/src/hooks/search/useSearchGuild.ts @@ -23,9 +23,14 @@ export const useSearchGuild = () => { const queryClient = useQueryClient() - const { data: guildsInfo, isLoading } = useQuery({ + const { + data: guildsInfo, + isLoading, + isError + } = useQuery({ queryKey: ['guildsInfo', serachGuildList, serachServer], - queryFn: () => searchGuildWithoutLogin(serachGuildList, serachServer) + queryFn: () => searchGuildWithoutLogin(serachGuildList, serachServer), + retry: false }) const mainCharacterInfoSearchMutation = useMutation({ @@ -119,6 +124,15 @@ export const useSearchGuild = () => { guild => guild.guildName === selectedGuild ) + const resetSearchParams = () => { + setSearchParams(new URLSearchParams()) + } + + if (isError) { + alert('길드 정보가 존재하지 않습니다.') + resetSearchParams() + } + return { searchGuildHandler, guildList, @@ -134,6 +148,7 @@ export const useSearchGuild = () => { removeGuildList, handleGuildKeyPress, selectedGuildMember, - mainCharacterInfoSearchHandler + mainCharacterInfoSearchHandler, + resetSearchParams } } diff --git a/src/pages/SearchGuild.tsx b/src/pages/SearchGuild.tsx index 60e6270..157b312 100644 --- a/src/pages/SearchGuild.tsx +++ b/src/pages/SearchGuild.tsx @@ -24,7 +24,8 @@ export const SearchGuild = () => { isLoading, selectedGuildMember, mainCharacterInfoSearchHandler, - isUpdating + isUpdating, + resetSearchParams } = useSearchGuild() const [searchCharacter, setSearchCharacter] = useState('') @@ -120,11 +121,29 @@ export const SearchGuild = () => {
) : (
-
+

길드 관리

길드원 정보 관리

+
From 193d67b4eabda2dd7bf3f777d9f1a4fb9215f5ee Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 16 Jun 2025 14:17:05 +0900 Subject: [PATCH 15/29] =?UTF-8?q?feat=20:=20=EA=B8=B8=EB=93=9C=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EB=B6=80=EC=BA=90=EB=A6=AD=ED=84=B0=20=EB=AA=A8?= =?UTF-8?q?=EB=8B=AC=20=EC=83=9D=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/guild/DetailMemberModal.tsx | 3 +- src/pages/Room.tsx | 2 +- src/pages/SearchGuild.tsx | 34 +++++++++++++++++-- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/components/modal/guild/DetailMemberModal.tsx b/src/components/modal/guild/DetailMemberModal.tsx index 1c07e09..edf4ae1 100644 --- a/src/components/modal/guild/DetailMemberModal.tsx +++ b/src/components/modal/guild/DetailMemberModal.tsx @@ -27,7 +27,8 @@ export const DetailMemberModal = ({ memberList.flatMap(n => n.memberDetailResponse ?.filter( - m => m.type === '부캐' && m.mainCharacterInfo?.id === memberDetail.id + m => + m.type === '부캐' && m.mainCharacterInfo?.name === memberDetail.name ) .map(m => ({ ...m, diff --git a/src/pages/Room.tsx b/src/pages/Room.tsx index a2df814..b313165 100644 --- a/src/pages/Room.tsx +++ b/src/pages/Room.tsx @@ -68,7 +68,7 @@ const Room = () => { mainChar: mainChar.character_name, subChar: member.name }) - openModal('alert') + openModal('alert') // 이거 나중에 삭제해야함 } catch { setAlertMessage({ mainChar: member.name, diff --git a/src/pages/SearchGuild.tsx b/src/pages/SearchGuild.tsx index 157b312..bd4481f 100644 --- a/src/pages/SearchGuild.tsx +++ b/src/pages/SearchGuild.tsx @@ -6,8 +6,10 @@ import { servers } from '../data/worlds' import { MemberContainer } from '../components/guild/MemberContainer' import { Empty } from '../components/common/Empty' import { ActionBtnList } from '../components/guild/ActionBtnList' -import { Guild } from '../types/guild' +import { Guild, Member } from '../types/guild' import { useState } from 'react' +import { useModalStore } from '../store/modalStore' +import { DetailMemberModal } from '../components/modal/guild/DetailMemberModal' export const SearchGuild = () => { const { @@ -29,11 +31,26 @@ export const SearchGuild = () => { } = useSearchGuild() const [searchCharacter, setSearchCharacter] = useState('') + const { activeModal, openModal } = useModalStore() + const [selectedMember, setSelectedMember] = useState<{ + type: string + member: Member | null + }>({ + type: '', + member: null + }) const handleSearchCharacter = (value: string) => { setSearchCharacter(value) } + const handleMemberSelect = async (type: string, member: Member) => { + setSelectedMember({ type: type, member: member }) + if (type !== '미지정') { + openModal('detailMember') + } + } + return (
{guildsInfo?.length === 0 ? ( @@ -185,7 +202,7 @@ export const SearchGuild = () => { }))} masterName={selectedGuildMember?.guildMasterName} guildName={selectedGuildMember?.guildName} - onSelect={() => {}} + onSelect={handleMemberSelect} searchCharacter={searchCharacter} setSearchCharacter={handleSearchCharacter} /> @@ -198,6 +215,19 @@ export const SearchGuild = () => {
)} + {activeModal === 'detailMember' && + selectedMember && + selectedMember.member && + guildsInfo && ( + ({ + guildName: v.guildName, + guildMasterName: v.guildMasterName, + memberDetailResponse: v.guildMember + }))} + /> + )}
) } From f3738d5d24c0fbe402c203c0c6d2e5b36ab4a1d5 Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 16 Jun 2025 14:27:55 +0900 Subject: [PATCH 16/29] =?UTF-8?q?feat=20:=20=EA=B8=B8=EB=93=9C=20=EB=A9=A4?= =?UTF-8?q?=EB=B3=B4=20=EC=B9=B4=EB=93=9C=202,=204,=208=EA=B0=9C=20?= =?UTF-8?q?=EB=B3=B4=EA=B8=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/guild/MemberContainer.tsx | 171 +++++++++++++---------- 1 file changed, 99 insertions(+), 72 deletions(-) diff --git a/src/components/guild/MemberContainer.tsx b/src/components/guild/MemberContainer.tsx index 78d9250..8f06e4d 100644 --- a/src/components/guild/MemberContainer.tsx +++ b/src/components/guild/MemberContainer.tsx @@ -4,7 +4,8 @@ import { IoChevronDown, IoEllipsisVertical, IoSearchOutline, - IoHelpCircleOutline + IoHelpCircleOutline, + IoGridOutline } from 'react-icons/io5' interface MemberContainerProps { @@ -36,6 +37,8 @@ export const MemberContainer = ({ const [selectedType, setSelectedType] = useState('캐릭터 분류') + const [gridSize, setGridSize] = useState(2) + const dropdownRef = useRef(null) if (!members) return null @@ -84,7 +87,7 @@ export const MemberContainer = ({ }) return ( -
+
{guildName && (
@@ -147,7 +150,7 @@ export const MemberContainer = ({ )}
-
+
-
- - - + {isOpen && ( +
+ + + + + +
+ )} +
- {isOpen && ( -
- - - - - -
- )} +
+ +
-
+
{filteredMembers.map(member => (
onSelect?.(member.type, member) } className="bg-gray-50 rounded-lg hover:bg-gray-100 transition-all duration-200 cursor-pointer group overflow-hidden border border-gray-100"> -
+
{member.name} -
+

{member.name}

{member.job}

-
-
-
+
+
+
Lv.{member.level} @@ -304,7 +330,8 @@ export const MemberContainer = ({ m => m.name === member.mainCharacterInfo?.name ) ) && ( - + 외부 길드에 {member.mainCharacterInfo?.name}님의 부캐입니다. From 8ac9d34d129a76393fadaaddc1f5458f9a8deb0e Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 16 Jun 2025 15:20:43 +0900 Subject: [PATCH 17/29] =?UTF-8?q?feat=20:=20=EA=B8=B8=EB=93=9C=20=EB=A9=A4?= =?UTF-8?q?=EB=B2=84=20=EB=B3=B8=EC=BA=90/=EB=B6=80=EC=BA=90/=EC=99=B8?= =?UTF-8?q?=EB=B6=80=20=EC=B4=9D=20=EC=9D=B8=EC=9B=90=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/guild/MemberContainer.tsx | 100 ++++++++++++++++------- src/hooks/search/useSearchGuild.ts | 3 +- 2 files changed, 71 insertions(+), 32 deletions(-) diff --git a/src/components/guild/MemberContainer.tsx b/src/components/guild/MemberContainer.tsx index 8f06e4d..a3abe3e 100644 --- a/src/components/guild/MemberContainer.tsx +++ b/src/components/guild/MemberContainer.tsx @@ -90,40 +90,78 @@ export const MemberContainer = ({
{guildName && (
-
-

- 길드: {guildName} -

-
- -
-
- - 본캐 - -

- 길드의 메인 캐릭터입니다. -

-
-
- - 부캐 - -

- 같은 길드 내 본캐가 있는 부캐릭터입니다. -

-
-
- - 외부 부캐 - -

- 다른 길드에 본캐가 있는 부캐릭터입니다. -

+
+
+

+ 길드: {guildName} +

+
+ +
+
+ + 본캐 + +

+ 길드의 메인 캐릭터입니다. +

+
+
+ + 부캐 + +

+ 같은 길드 내 본캐가 있는 부캐릭터입니다. +

+
+
+ + 외부 부캐 + +

+ 다른 길드에 본캐가 있는 부캐릭터입니다. +

+
+
-
+
+

+ 총 인원 : {members.length} +

+

+ 본캐 : {members.filter(member => member.type === '본캐').length} +

+

+ 부캐 : + { + members.filter( + member => + member.type === '부캐' && + allMembers?.find(m => + m.memberDetailResponse?.find( + m => m.name === member.mainCharacterInfo?.name + ) + ) + ).length + } +

+

+ 외부 부캐 : + { + members.filter( + member => + member.type === '부캐' && + !allMembers?.some(m => + m.memberDetailResponse?.some( + m => m.name === member.mainCharacterInfo?.name + ) + ) + ).length + } +

+
{onDeleteGuild && !isMainGuild && (
diff --git a/src/hooks/search/useSearchGuild.ts b/src/hooks/search/useSearchGuild.ts index 8519a7c..f31f774 100644 --- a/src/hooks/search/useSearchGuild.ts +++ b/src/hooks/search/useSearchGuild.ts @@ -30,7 +30,8 @@ export const useSearchGuild = () => { } = useQuery({ queryKey: ['guildsInfo', serachGuildList, serachServer], queryFn: () => searchGuildWithoutLogin(serachGuildList, serachServer), - retry: false + retry: false, + staleTime: 1000 * 60 * 5 }) const mainCharacterInfoSearchMutation = useMutation({ From f173566c5cff0a9dfb7a7d7ba179f6554969585c Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 16 Jun 2025 15:28:31 +0900 Subject: [PATCH 18/29] =?UTF-8?q?style=20:=20=EB=B3=B8=EC=BA=90/=EB=B6=80?= =?UTF-8?q?=EC=BA=90=20=EC=A1=B0=ED=9A=8C=20=EB=B2=84=ED=8A=BC=20=EB=94=94?= =?UTF-8?q?=EC=9E=90=EC=9D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/guild/ActionBtnList.tsx | 39 ++++++++++++++++++-------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/components/guild/ActionBtnList.tsx b/src/components/guild/ActionBtnList.tsx index 455d111..5258ea1 100644 --- a/src/components/guild/ActionBtnList.tsx +++ b/src/components/guild/ActionBtnList.tsx @@ -147,22 +147,37 @@ export const ActionBtnList = ({ )}
) : ( -
- {guildList.map(guild => ( - - ))} +
+
+ {guildList.map(guild => ( + + ))} +
From b23c6f3af5e0f1d21e97fa0e93ca15a0852e1c49 Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 16 Jun 2025 15:42:26 +0900 Subject: [PATCH 19/29] =?UTF-8?q?fix=20:=20=EC=BA=90=EB=A6=AD=ED=84=B0=20?= =?UTF-8?q?=EC=84=A4=EB=AA=85=20=EC=97=86=EC=9D=84=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?=EB=B6=80=EC=BA=90=EB=A6=AD=20=EB=AA=A9=EB=A1=9D=20=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/modal/guild/DetailMemberModal.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/modal/guild/DetailMemberModal.tsx b/src/components/modal/guild/DetailMemberModal.tsx index edf4ae1..3114e3a 100644 --- a/src/components/modal/guild/DetailMemberModal.tsx +++ b/src/components/modal/guild/DetailMemberModal.tsx @@ -21,7 +21,9 @@ export const DetailMemberModal = ({ }: Props) => { const [isEditMode, setIsEditMode] = useState(false) const [description, setDescription] = useState(memberDetail.description || '') - const [selectedTab, setSelectedTab] = useState<'info' | 'alts'>('info') + const [selectedTab, setSelectedTab] = useState<'info' | 'alts'>( + memberDetail.description ? 'info' : 'alts' + ) const subCharacterList = memberList.flatMap(n => From b5b42402e780372fe1b0a07d2b60777992fdabd5 Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 16 Jun 2025 16:05:02 +0900 Subject: [PATCH 20/29] =?UTF-8?q?style=20:=20=EA=B8=B8=EB=93=9C=20?= =?UTF-8?q?=EB=A7=88=EC=8A=A4=ED=84=B0=20=ED=83=80=EC=9E=85=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/guild/MemberContainer.tsx | 53 +++++++++++++++--------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/src/components/guild/MemberContainer.tsx b/src/components/guild/MemberContainer.tsx index a3abe3e..61f432a 100644 --- a/src/components/guild/MemberContainer.tsx +++ b/src/components/guild/MemberContainer.tsx @@ -331,9 +331,35 @@ export const MemberContainer = ({ {masterName && ( + m.memberDetailResponse?.find( + m => + m.name === + member.mainCharacterInfo?.name + ) + ) + ? 'bg-purple-100 text-purple-700' + : 'bg-gray-100 text-gray-700' + }`}> + {member.name === masterName && ( + + + + )} + {member.name === masterName + ? '마스터' + : member.type === '본캐' + ? '본캐' : member.type === '부캐' && allMembers?.find(m => m.memberDetailResponse?.find( @@ -342,23 +368,10 @@ export const MemberContainer = ({ member.mainCharacterInfo?.name ) ) - ? 'bg-yellow-100 text-yellow-700' - : 'bg-gray-100 text-gray-700' - }`}> - {member.type === '본캐' - ? '본캐' - : member.type === '부캐' && - allMembers?.find(m => - m.memberDetailResponse?.find( - m => - m.name === - member.mainCharacterInfo?.name - ) - ) - ? '부캐' - : member.mainCharacterInfo === null - ? '' - : '외부 부캐'} + ? '부캐' + : member.mainCharacterInfo === null + ? '' + : '외부 부캐'} )}
From 051caadddd0899eb0aa395f32772708d17f2010f Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 16 Jun 2025 16:43:59 +0900 Subject: [PATCH 21/29] =?UTF-8?q?style=20:=20=EB=B6=80=EC=BA=90=EB=A6=AD?= =?UTF-8?q?=ED=84=B0=20=ED=83=80=EC=9E=85=20=EC=83=89=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/guild/MemberContainer.tsx | 2 +- src/hooks/search/useSearchGuild.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/guild/MemberContainer.tsx b/src/components/guild/MemberContainer.tsx index 61f432a..f78f22c 100644 --- a/src/components/guild/MemberContainer.tsx +++ b/src/components/guild/MemberContainer.tsx @@ -344,7 +344,7 @@ export const MemberContainer = ({ member.mainCharacterInfo?.name ) ) - ? 'bg-purple-100 text-purple-700' + ? 'bg-yellow-100 text-yellow-700' : 'bg-gray-100 text-gray-700' }`}> {member.name === masterName && ( diff --git a/src/hooks/search/useSearchGuild.ts b/src/hooks/search/useSearchGuild.ts index f31f774..b95a7e5 100644 --- a/src/hooks/search/useSearchGuild.ts +++ b/src/hooks/search/useSearchGuild.ts @@ -31,7 +31,7 @@ export const useSearchGuild = () => { queryKey: ['guildsInfo', serachGuildList, serachServer], queryFn: () => searchGuildWithoutLogin(serachGuildList, serachServer), retry: false, - staleTime: 1000 * 60 * 5 + staleTime: 1000 * 60 * 10 }) const mainCharacterInfoSearchMutation = useMutation({ From 0f6578e4b405f0f43690b7f4d7a5b684d808757f Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 17 Jun 2025 12:15:06 +0900 Subject: [PATCH 22/29] =?UTF-8?q?feat=20:=20=EC=BA=90=EB=A6=AD=ED=84=B0=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84,=20=EB=A0=88=EB=B2=A8=20=EC=A0=95=EB=A0=AC?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/guild/MemberContainer.tsx | 99 +++++++++++++++++------- 1 file changed, 73 insertions(+), 26 deletions(-) diff --git a/src/components/guild/MemberContainer.tsx b/src/components/guild/MemberContainer.tsx index f78f22c..659a73a 100644 --- a/src/components/guild/MemberContainer.tsx +++ b/src/components/guild/MemberContainer.tsx @@ -35,6 +35,9 @@ export const MemberContainer = ({ const [isOpen, setIsOpen] = useState(false) + const [sortType, setSortType] = useState('캐릭터 정렬') + const [sortTypeOpen, setSortTypeOpen] = useState(false) + const [selectedType, setSelectedType] = useState('캐릭터 분류') const [gridSize, setGridSize] = useState(2) @@ -51,40 +54,49 @@ export const MemberContainer = ({ setShowMenu(false) } - const filteredMembers = members.filter(member => { - if (selectedType === '모두 보기' || selectedType === '캐릭터 분류') - return member.name + const filteredMembers = members + .filter(member => { + const searchMatch = member.name .toLowerCase() .includes(searchCharacter?.toLowerCase() || '') - if (selectedType === '본캐') - return ( - member.type === '본캐' && - member.name.toLowerCase().includes(searchCharacter?.toLowerCase() || '') - ) - if (selectedType === '부캐') + + if (selectedType === '모두 보기' || selectedType === '캐릭터 분류') + return searchMatch + + if (selectedType === '본캐') return member.type === '본캐' && searchMatch + + if (selectedType === '부캐') + return ( + member.type === '부캐' && + allMembers?.find(m => + m.memberDetailResponse?.find( + m => m.name === member.mainCharacterInfo?.name + ) + ) && + searchMatch + ) + + if (selectedType === '특이사항') return member.description && searchMatch + return ( member.type === '부캐' && - allMembers?.find(m => + !allMembers?.find(m => m.memberDetailResponse?.find( m => m.name === member.mainCharacterInfo?.name ) ) && - member.name.toLowerCase().includes(searchCharacter?.toLowerCase() || '') + searchMatch ) - if (selectedType === '특이사항') - return ( - member.description && - member.name.toLowerCase().includes(searchCharacter?.toLowerCase() || '') - ) - return ( - member.type === '부캐' && - !allMembers?.find(m => - m.memberDetailResponse?.find( - m => m.name === member.mainCharacterInfo?.name - ) - ) - ) - }) + }) + .sort((a, b) => { + if (sortType === '이름순') { + return a.name.localeCompare(b.name) + } + if (sortType === '레벨순') { + return Number(b.level) - Number(a.level) + } + return 0 + }) return (
@@ -201,6 +213,41 @@ export const MemberContainer = ({
+
+ + + {sortTypeOpen && ( +
+ + +
+ )} +
@@ -220,7 +267,7 @@ export const MemberContainer = ({ {isOpen && ( -
+
- {recentNotices.map(notice => ( + {recentNotices.reverse().map(notice => ( - {filteredItems.map(item => ( + {filteredItems.reverse().map(item => (
From ec3b00efb1db76f53cf676c84d3615e8c344c820 Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 17 Jun 2025 16:26:51 +0900 Subject: [PATCH 24/29] =?UTF-8?q?fix=20:=20useQuery=20enabled=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=EA=B8=B8=EB=93=9C=20=EA=B0=B1=EC=8B=A0?= =?UTF-8?q?=20=EB=AC=B8=EA=B5=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/guild/ActionBtnList.tsx | 37 ++++++++++++------------ src/components/guild/MemberContainer.tsx | 2 +- src/hooks/calendar/useUserNotice.ts | 2 +- src/hooks/guild/useGuildMember.ts | 2 +- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/components/guild/ActionBtnList.tsx b/src/components/guild/ActionBtnList.tsx index 5258ea1..fb37c22 100644 --- a/src/components/guild/ActionBtnList.tsx +++ b/src/components/guild/ActionBtnList.tsx @@ -185,6 +185,24 @@ export const ActionBtnList = ({ {handleDetect && showModal && (
+
+ +
+
+ 기록된 길드원 정보와 게임 내 정보를 비교하고 변경합니다. +
+ ⭐︎ 길드원 변동이 있을경우 꼭 눌러주세요. ⭐︎ +
+
+
{
-
- -
- -
-
- 기록된 길드원 정보를 게임 내 정보와 비교합니다. + 캐릭터의 본/부캐 정보가 오류 있을 경우 새로고침합니다.
diff --git a/src/components/guild/MemberContainer.tsx b/src/components/guild/MemberContainer.tsx index 659a73a..f61fe83 100644 --- a/src/components/guild/MemberContainer.tsx +++ b/src/components/guild/MemberContainer.tsx @@ -138,7 +138,7 @@ export const MemberContainer = ({
-
+

총 인원 : {members.length}

diff --git a/src/hooks/calendar/useUserNotice.ts b/src/hooks/calendar/useUserNotice.ts index d64e400..318a46b 100644 --- a/src/hooks/calendar/useUserNotice.ts +++ b/src/hooks/calendar/useUserNotice.ts @@ -20,7 +20,7 @@ export const useUserNotice = () => { const { data, isLoading } = useQuery({ queryKey: ['calendar'], queryFn: getCalendar, - enabled: userType !== 'guest' + enabled: userType === 'member' }) const createPersonalCalendarMutation = useMutation({ diff --git a/src/hooks/guild/useGuildMember.ts b/src/hooks/guild/useGuildMember.ts index ab3b1ea..629134d 100644 --- a/src/hooks/guild/useGuildMember.ts +++ b/src/hooks/guild/useGuildMember.ts @@ -28,7 +28,7 @@ export const useGuildMember = () => { queryFn: () => Promise.all(guildList?.map(v => fetchGuildMembers(v.guildId ?? 0)) || []), staleTime: 1000 * 60 * 10, - enabled: userType !== 'guest' + enabled: userType === 'member' }) if (userType === 'guest') { From 1fcc4c20bad15fa1aaed584b8d678a26c300ea49 Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 17 Jun 2025 17:36:46 +0900 Subject: [PATCH 25/29] =?UTF-8?q?fix=20:=20=EC=BA=90=EB=A6=AD=ED=84=B0?= =?UTF-8?q?=ED=84=B0=20ocid=20=EC=A0=80=EC=9E=A5=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=83=81=ED=83=9C?= =?UTF-8?q?=EC=97=90=EB=8F=84=20=EC=BA=90=EB=A6=AD=ED=84=B0=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EA=B0=80=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/character/CharacterPage.tsx | 66 ++++++++++++---------- src/hooks/character/useCharacterData.ts | 27 +++++---- src/hooks/character/useInventory.ts | 8 +-- src/pages/Character.tsx | 2 +- src/pages/Home.tsx | 5 +- src/pages/SearchCharacter.tsx | 36 +----------- src/pages/Signup.tsx | 3 +- src/store/userStore.ts | 10 ++-- 8 files changed, 70 insertions(+), 87 deletions(-) diff --git a/src/components/character/CharacterPage.tsx b/src/components/character/CharacterPage.tsx index e7e93ae..2b2e1e8 100644 --- a/src/components/character/CharacterPage.tsx +++ b/src/components/character/CharacterPage.tsx @@ -7,26 +7,35 @@ import { StatContainer } from './StatContainer' import { useCharacterData } from '../../hooks/character/useCharacterData' import { useInventory } from '../../hooks/character/useInventory' import { useNavigate } from 'react-router-dom' +import { useUserStore } from '../../store/userStore' +import { searchCharacterOcid } from '../../apis/character/characterController' -interface CharacterPageProps { - type: 'character' | 'search' - characterName?: string - setCharacterName?: (characterName: string) => void - searchCharacterHandler?: () => Promise -} -export const CharacterPage = ({ - type, - characterName, - setCharacterName, - searchCharacterHandler -}: CharacterPageProps) => { +export const CharacterPage = () => { const { characterStats, ability, hyperStat, basic, isLoading, error } = useCharacterData() + const [characterName, setCharacterName] = useState('') const { inventory } = useInventory() const [showStats, setShowStats] = useState(true) const nav = useNavigate() + const { setCharacterOcid } = useUserStore() + + const searchCharacterHandler = async () => { + if (characterName.trim() === '') { + alert('캐릭터 이름을 입력해주세요.') + return + } + + const { ocid } = await searchCharacterOcid(characterName.trim()) + + if (!ocid) { + alert('캐릭터를 찾을 수 없습니다.') + return + } + + setCharacterOcid(ocid) + } if (isLoading) { return ( @@ -73,24 +82,21 @@ export const CharacterPage = ({ 장비 정보
- {type === 'search' ? ( -
- setCharacterName?.(e.target.value)} - /> - -
- ) : ( -
{/* 오른쪽 여백을 위한 빈 div */}
- )} + +
+ setCharacterName?.(e.target.value)} + /> + +
{/* 콘텐츠 영역 */} diff --git a/src/hooks/character/useCharacterData.ts b/src/hooks/character/useCharacterData.ts index 629f5f6..6f8cac6 100644 --- a/src/hooks/character/useCharacterData.ts +++ b/src/hooks/character/useCharacterData.ts @@ -16,16 +16,17 @@ import { useUserStore } from '../../store/userStore' import { useEffect } from 'react' export const useCharacterData = () => { - const { userInfo, setUserName } = useUserStore() - const ocid = userInfo?.ocid + const { setUserName, characterOcid } = useUserStore() const { data: characterStats, isLoading: statsLoading, error: statsError } = useQuery({ - queryKey: ['characterStats', ocid], - queryFn: ocid ? () => fetchCharacterStat(ocid) : undefined, + queryKey: ['characterStats', characterOcid], + queryFn: characterOcid + ? () => fetchCharacterStat(characterOcid) + : undefined, staleTime: 5 * 60 * 1000, retry: false }) @@ -35,8 +36,10 @@ export const useCharacterData = () => { isLoading: abilityLoading, error: abilityError } = useQuery({ - queryKey: ['characterAbility', ocid], - queryFn: ocid ? () => fetchCharacterAbility(ocid) : undefined, + queryKey: ['characterAbility', characterOcid], + queryFn: characterOcid + ? () => fetchCharacterAbility(characterOcid) + : undefined, staleTime: 5 * 60 * 1000, retry: false }) @@ -46,8 +49,10 @@ export const useCharacterData = () => { isLoading: hyperLoading, error: hyperError } = useQuery({ - queryKey: ['characterHyperStat', ocid], - queryFn: ocid ? () => fetchCharacterHyperStat(ocid) : undefined, + queryKey: ['characterHyperStat', characterOcid], + queryFn: characterOcid + ? () => fetchCharacterHyperStat(characterOcid) + : undefined, staleTime: 5 * 60 * 1000, retry: false }) @@ -57,8 +62,10 @@ export const useCharacterData = () => { isLoading: basicLoading, error: basicError } = useQuery({ - queryKey: ['characterBasic', ocid], - queryFn: ocid ? () => fetchCharacterBasic(ocid) : undefined, + queryKey: ['characterBasic', characterOcid], + queryFn: characterOcid + ? () => fetchCharacterBasic(characterOcid) + : undefined, staleTime: 5 * 60 * 1000, retry: false }) diff --git a/src/hooks/character/useInventory.ts b/src/hooks/character/useInventory.ts index 064bd64..40f3cfb 100644 --- a/src/hooks/character/useInventory.ts +++ b/src/hooks/character/useInventory.ts @@ -4,12 +4,12 @@ import { fetchCharacterItem } from '../../apis/character/characterController' import { Inventory } from '../../types/item' export const useInventory = () => { - const { userInfo } = useUserStore() + const { characterOcid } = useUserStore() const { data: inventory, isLoading: inventoryLoading } = useQuery({ - queryKey: ['inventory', userInfo?.ocid], - queryFn: () => fetchCharacterItem(userInfo!.ocid!), + queryKey: ['inventory', characterOcid], + queryFn: () => fetchCharacterItem(characterOcid!), staleTime: 5 * 60 * 1000, - enabled: !!userInfo?.ocid + enabled: !!characterOcid }) return { inventory, inventoryLoading } diff --git a/src/pages/Character.tsx b/src/pages/Character.tsx index 1ec2480..743c65c 100644 --- a/src/pages/Character.tsx +++ b/src/pages/Character.tsx @@ -1,7 +1,7 @@ import { CharacterPage } from '../components/character/CharacterPage' const Character = () => { - return + return } export default Character diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index da8ce17..ac66e9d 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -21,7 +21,7 @@ import { servers } from '../data/worlds' const Home = () => { const { userLogin } = useAuth() const { storeLogin } = useAuthStore() - const { setUserInfo, updateUserInfo } = useUserStore() + const { setUserInfo, setCharacterOcid } = useUserStore() const nav = useNavigate() const KAKAO_CHAT_LINK = 'https://open.kakao.com/o/s4tfG2Ah' @@ -50,6 +50,7 @@ const Home = () => { const userInfo = await userLogin() if (userInfo) { setUserInfo(userInfo) + setCharacterOcid(userInfo.ocid!) if (userInfo?.nexonApiKey) { nav('/character') } else { @@ -76,7 +77,7 @@ const Home = () => { } await storeLogin('', '', 'search') - updateUserInfo({ ocid }) + setCharacterOcid(ocid) nav(`/searchCharacter`) } const onSearchGuild = async () => { diff --git a/src/pages/SearchCharacter.tsx b/src/pages/SearchCharacter.tsx index a578277..9ca9202 100644 --- a/src/pages/SearchCharacter.tsx +++ b/src/pages/SearchCharacter.tsx @@ -1,39 +1,5 @@ -import { searchCharacterOcid } from '../apis/character/characterController' import { CharacterPage } from '../components/character/CharacterPage' -import { useState } from 'react' -import { useUserStore } from '../store/userStore' export const SearchCharacter = () => { - const [characterName, setCharacterName] = useState('') - const { setUserInfo } = useUserStore() - - const searchCharacterHandler = async () => { - if (characterName.trim() === '') { - alert('캐릭터 이름을 입력해주세요.') - return - } - - const { ocid } = await searchCharacterOcid(characterName.trim()) - - if (!ocid) { - alert('캐릭터를 찾을 수 없습니다.') - return - } - - setUserInfo({ - id: 0, - firebaseId: '1', - name: characterName.trim(), - email: 'play3step@gmail.com', - ocid: ocid - }) - } - return ( - - ) + return } diff --git a/src/pages/Signup.tsx b/src/pages/Signup.tsx index 20ab52c..00900ff 100644 --- a/src/pages/Signup.tsx +++ b/src/pages/Signup.tsx @@ -15,7 +15,7 @@ const Signup = () => { const { userLogout } = useAuth() const { uid } = useAuthStore() - const { updateUserInfo } = useUserStore() + const { updateUserInfo, setCharacterOcid } = useUserStore() const onSubmit = async (e: React.FormEvent) => { e.preventDefault() @@ -41,6 +41,7 @@ const Signup = () => { nexonApiKey: result.generatedApiKey, ocid: result.characterUid }) + setCharacterOcid(result.characterUid) alert('API 키 등록이 완료되었습니다.') diff --git a/src/store/userStore.ts b/src/store/userStore.ts index 6bf170e..cb0f681 100644 --- a/src/store/userStore.ts +++ b/src/store/userStore.ts @@ -5,10 +5,11 @@ import { guest } from '../data/guest' interface UserState { userInfo: User | null userName: string | null + characterOcid: string setUserInfo: (info: User) => void setUserName: (name: string) => void - + setCharacterOcid: (ocid: string) => void updateUserInfo: (info: Partial) => void clearUserInfo: () => void } @@ -22,13 +23,14 @@ export const useUserStore = create(set => ({ ocid: guest.ocid }, userName: null, - + characterOcid: guest.ocid, setUserInfo: info => set({ userInfo: info }), setUserName: name => set({ userName: name }), - + setCharacterOcid: ocid => set({ characterOcid: ocid }), updateUserInfo: info => set(state => ({ userInfo: state.userInfo ? { ...state.userInfo, ...info } : null })), - clearUserInfo: () => set({ userInfo: null, userName: null }) + clearUserInfo: () => + set({ userInfo: null, userName: null, characterOcid: guest.ocid }) })) From 98b41cb5d0c71635ee48a8fc238d6ffddc89aecd Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 17 Jun 2025 19:20:21 +0900 Subject: [PATCH 26/29] =?UTF-8?q?fix=20:=20=EB=B3=B8=EC=BA=90/=EB=B6=80?= =?UTF-8?q?=EC=BA=90=20=EC=A1=B0=ED=9A=8C=20=EB=A1=9C=EB=94=A9=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/guild/ActionBtnList.tsx | 13 ++++++++++--- src/pages/SearchGuild.tsx | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/components/guild/ActionBtnList.tsx b/src/components/guild/ActionBtnList.tsx index fb37c22..45ea22b 100644 --- a/src/components/guild/ActionBtnList.tsx +++ b/src/components/guild/ActionBtnList.tsx @@ -16,6 +16,7 @@ interface Props { handleDetect?: () => void refreshMember?: (guildId: number) => void mainCharacterInfoSearchHandler?: () => void + isUpdating?: boolean } export const ActionBtnList = ({ @@ -23,7 +24,8 @@ export const ActionBtnList = ({ guildList, handleDetect, refreshMember, - mainCharacterInfoSearchHandler + mainCharacterInfoSearchHandler, + isUpdating }: Props) => { const [searchParams, setSearchParams] = useSearchParams() const [selectedGuild, setSelectedGuild] = useState(null) @@ -164,7 +166,12 @@ export const ActionBtnList = ({ onClick={() => { mainCharacterInfoSearchHandler?.() }} - className="sm:w-32 shrink-0 bg-blue-500 hover:bg-blue-600 text-white rounded-lg px-1 py-2 text-sm font-medium transition-colors duration-200 flex items-center justify-center gap-2 shadow-sm"> + disabled={isUpdating} + className={`sm:w-32 shrink-0 ${ + isUpdating + ? 'bg-blue-300 cursor-not-allowed' + : 'bg-blue-500 hover:bg-blue-600' + } text-white rounded-lg px-1 py-2 text-sm font-medium transition-colors duration-200 flex items-center justify-center gap-2 shadow-sm`}> - 본캐/부캐 조회 + {isUpdating ? '조회 중...' : '본캐/부캐 조회'}
)} diff --git a/src/pages/SearchGuild.tsx b/src/pages/SearchGuild.tsx index bd4481f..c470255 100644 --- a/src/pages/SearchGuild.tsx +++ b/src/pages/SearchGuild.tsx @@ -176,6 +176,7 @@ export const SearchGuild = () => { mainCharacterInfoSearchHandler={ mainCharacterInfoSearchHandler } + isUpdating={isUpdating} />
From 914e3c86620d5084c44e6dfaf23a5caafe8dadcc Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 17 Jun 2025 19:35:52 +0900 Subject: [PATCH 27/29] =?UTF-8?q?style=20:=20=EB=B6=80=EC=BA=90=EB=A6=AD?= =?UTF-8?q?=ED=84=B0=20=EC=B4=9D=20=EC=88=98=20=EC=8A=A4=ED=83=80=EC=9D=BC?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/modal/guild/DetailMemberModal.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/modal/guild/DetailMemberModal.tsx b/src/components/modal/guild/DetailMemberModal.tsx index 3114e3a..203c489 100644 --- a/src/components/modal/guild/DetailMemberModal.tsx +++ b/src/components/modal/guild/DetailMemberModal.tsx @@ -114,6 +114,9 @@ export const DetailMemberModal = ({

부캐릭터 목록

+

+ 부캐릭터 총 {subCharacterList.length}개 +

{subCharacterList.map(alt => ( From 738de02dbcb46005d8083eea3aac427fb9243c47 Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 17 Jun 2025 19:45:53 +0900 Subject: [PATCH 28/29] =?UTF-8?q?fix=20:=20=EB=B3=B8/=EB=B6=80=EC=BA=90=20?= =?UTF-8?q?=EA=B0=B1=EC=8B=A0=20disabled=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/guild/ActionBtnList.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/guild/ActionBtnList.tsx b/src/components/guild/ActionBtnList.tsx index 45ea22b..f9ccac0 100644 --- a/src/components/guild/ActionBtnList.tsx +++ b/src/components/guild/ActionBtnList.tsx @@ -213,6 +213,7 @@ export const ActionBtnList = ({
{
diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index ac66e9d..326bfd2 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -17,11 +17,13 @@ import Button from '../components/common/Button' import { searchCharacterOcid } from '../apis/character/characterController' import { useSearchGuild } from '../hooks/search/useSearchGuild' import { servers } from '../data/worlds' +import { guest } from '../data/guest' const Home = () => { const { userLogin } = useAuth() const { storeLogin } = useAuthStore() const { setUserInfo, setCharacterOcid } = useUserStore() + const [searchLoading, setSearchLoading] = useState(false) const nav = useNavigate() const KAKAO_CHAT_LINK = 'https://open.kakao.com/o/s4tfG2Ah' @@ -41,6 +43,7 @@ const Home = () => { const handleGuestLogin = async () => { await storeLogin('', '', 'guest') + setCharacterOcid(guest.ocid) nav('/character') } @@ -69,6 +72,7 @@ const Home = () => { return } + setSearchLoading(true) const { ocid } = await searchCharacterOcid(characterName.trim()) if (!ocid) { @@ -79,7 +83,9 @@ const Home = () => { await storeLogin('', '', 'search') setCharacterOcid(ocid) nav(`/searchCharacter`) + setSearchLoading(false) } + const onSearchGuild = async () => { nav(`/searchGuild`) searchGuildHandler() @@ -292,9 +298,14 @@ const Home = () => {