From 14ff0093c2b3bf7c63ad05f3f163fda62bbaa2fd Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 5 Sep 2025 21:37:39 +0900 Subject: [PATCH 1/6] =?UTF-8?q?[Refactor]=20=ED=99=88=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20=EB=B0=8F=20=EB=8B=A8=EC=9D=BC=20=EC=B1=85=EC=9E=84?= =?UTF-8?q?=20=EA=B0=80=EC=A7=80=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/CharacterSearchSection.tsx | 75 ++++ src/components/home/FeatureShowcase.tsx | 64 +++ src/components/home/GuildSearchSection.tsx | 111 ++++++ src/components/home/HeroSection.tsx | 80 ++++ src/components/home/HomeNavigation.tsx | 42 ++ src/data/notices.ts | 27 ++ src/pages/Home.tsx | 372 +----------------- 7 files changed, 413 insertions(+), 358 deletions(-) create mode 100644 src/components/home/CharacterSearchSection.tsx create mode 100644 src/components/home/FeatureShowcase.tsx create mode 100644 src/components/home/GuildSearchSection.tsx create mode 100644 src/components/home/HeroSection.tsx create mode 100644 src/components/home/HomeNavigation.tsx create mode 100644 src/data/notices.ts diff --git a/src/components/home/CharacterSearchSection.tsx b/src/components/home/CharacterSearchSection.tsx new file mode 100644 index 0000000..ccfe9e1 --- /dev/null +++ b/src/components/home/CharacterSearchSection.tsx @@ -0,0 +1,75 @@ +import { useState } from 'react' +import { useNavigate } from 'react-router-dom' +import { FiSearch } from 'react-icons/fi' +import { useAuthStore } from '../../store/authStore' +import { useUserStore } from '../../store/userStore' +import { searchCharacterOcid } from '../../apis/character/characterController' +import Button from '../common/Button' + +const CharacterSearchSection = () => { + const [characterName, setCharacterName] = useState('') + const [searchLoading, setSearchLoading] = useState(false) + const { storeLogin } = useAuthStore() + const { setCharacterOcid } = useUserStore() + const nav = useNavigate() + + const searchCharacterHandler = async () => { + if (characterName.trim() === '') { + alert('캐릭터 이름을 입력해주세요.') + return + } + + setSearchLoading(true) + try { + const { ocid } = await searchCharacterOcid(characterName.trim()) + + if (!ocid) { + alert('캐릭터를 찾을 수 없습니다.') + return + } + await storeLogin('', '', 'search') + setCharacterOcid(ocid) + nav('/searchCharacter') + } catch { + alert('캐릭터 검색에 실패했습니다.') + } finally { + setSearchLoading(false) + } + } + + return ( +
+
+
+
+ +
+

캐릭터 검색

+
+
+ setCharacterName(e.target.value)} + className="w-full px-4 py-2.5 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm bg-white" + /> + +
+
+
+ ) +} + +export default CharacterSearchSection diff --git a/src/components/home/FeatureShowcase.tsx b/src/components/home/FeatureShowcase.tsx new file mode 100644 index 0000000..a810fc4 --- /dev/null +++ b/src/components/home/FeatureShowcase.tsx @@ -0,0 +1,64 @@ +import { FiCalendar } from 'react-icons/fi' +import { useAuthStore } from '../../store/authStore' +import { useUserStore } from '../../store/userStore' +import { useNavigate } from 'react-router-dom' +import { guest } from '../../data/guest' +import Button from '../common/Button' + +const FeatureShowcase = () => { + const { storeLogin } = useAuthStore() + const { setCharacterOcid } = useUserStore() + const nav = useNavigate() + + const handleGuestLogin = async () => { + await storeLogin('', '', 'guest') + setCharacterOcid(guest.ocid) + nav('/character') + } + + return ( +
+
+
+ +
+

체험하기

+
+
+
+

비로그인 이용 가능한 기능

+
+ + 캐릭터 정보 조회 +
+
+ + 길드 정보 조회 +
+
+
+

+ 로그인 후 이용 가능한 기능 +

+
+ + 캘린더로 일정 관리하기 +
+
+ + 길드원 관리하기 +
+
+ +
+
+ ) +} + +export default FeatureShowcase diff --git a/src/components/home/GuildSearchSection.tsx b/src/components/home/GuildSearchSection.tsx new file mode 100644 index 0000000..6920b0d --- /dev/null +++ b/src/components/home/GuildSearchSection.tsx @@ -0,0 +1,111 @@ +import { useNavigate } from 'react-router-dom' +import { FiUsers } from 'react-icons/fi' +import { useSearchGuild } from '../../hooks/search/useSearchGuild' +import { servers } from '../../data/worlds' +import Button from '../common/Button' + +const GuildSearchSection = () => { + const nav = useNavigate() + const { + selectedServer, + setSelectedServer, + guildList, + searchGuildHandler, + addGuildList, + removeGuildList, + handleGuildKeyPress, + guildName, + setGuildName + } = useSearchGuild() + + const onSearchGuild = async () => { + nav('/searchGuild') + searchGuildHandler() + } + + return ( +
+
+
+
+ +
+

+ 길드 검색 (최대 4개 검색 가능) +

+
+
+
+ + 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" + /> + +
+ +
+

검색할 길드 목록

+
+ {guildList.map(guild => ( +
+ {guild} + +
+ ))} +
+
+ + +
+
+
+ ) +} + +export default GuildSearchSection diff --git a/src/components/home/HeroSection.tsx b/src/components/home/HeroSection.tsx new file mode 100644 index 0000000..24e0018 --- /dev/null +++ b/src/components/home/HeroSection.tsx @@ -0,0 +1,80 @@ +import { useNavigate } from 'react-router-dom' +import { useAuth } from '../../hooks/useAuth' +import { useAuthStore } from '../../store/authStore' +import { useUserStore } from '../../store/userStore' +import { guest } from '../../data/guest' +import Logo from '../../assets/logo.png' +import GoogleLogo from '../../assets/gogle.svg' + +const HeroSection = () => { + const { userLogin } = useAuth() + const { storeLogin } = useAuthStore() + const { setUserInfo, setCharacterOcid } = useUserStore() + const nav = useNavigate() + + const handleGuestLogin = async () => { + await storeLogin('', '', 'guest') + setCharacterOcid(guest.ocid) + nav('/character') + } + + const handleMemberLogin = async () => { + try { + const userInfo = await userLogin() + if (userInfo) { + setUserInfo(userInfo) + setCharacterOcid(userInfo.ocid!) + if (userInfo?.nexonApiKey) { + nav('/character') + } else { + nav('/signup') + } + } + } catch { + alert('로그인에 실패했습니다.') + } + } + + return ( +
+
+ 메이플링크 로고 +
+ + + 메이플스토리 통합 관리 플랫폼 + +
+
+

+ 메이플스토리를 더 스마트하게 +

+

+ 캐릭터부터 길드까지, 한눈에 관리하세요 +

+
+ + +
+
+ ) +} + +export default HeroSection diff --git a/src/components/home/HomeNavigation.tsx b/src/components/home/HomeNavigation.tsx new file mode 100644 index 0000000..1e660e9 --- /dev/null +++ b/src/components/home/HomeNavigation.tsx @@ -0,0 +1,42 @@ +import { Link } from 'react-router-dom' +import Logo from '../../assets/logo.png' +import KakaoOpenChatButton from '../common/KakaoOpenChatButton' + +const KAKAO_CHAT_LINK = 'https://open.kakao.com/o/s4tfG2Ah' + +const HomeNavigation = () => { + return ( + + ) +} + +export default HomeNavigation diff --git a/src/data/notices.ts b/src/data/notices.ts new file mode 100644 index 0000000..0945b10 --- /dev/null +++ b/src/data/notices.ts @@ -0,0 +1,27 @@ +export const recentNotices = [ + { + id: 1, + title: '서비스 이용 안내', + date: '2025.05.23' + }, + { + id: 2, + title: '메이플스토리 캘린더 업데이트 안내', + date: '2025.06.11' + }, + { + id: 3, + title: '다음 업데이트 예정 기능', + date: '2025.06' + }, + { + id: 4, + title: '메이플링크 비로그인 기능 업데이트 안내', + date: '2025.06.17' + }, + { + id: 5, + title: '챌린저스 서버 길드 검색 / 길드 관리 기능 업데이트 안내', + date: '2025.06.23' + } +] diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 0a2c66c..e8db75a 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -1,369 +1,25 @@ -import { useNavigate, Link } from 'react-router-dom' -import { useAuth } from '../hooks/useAuth' -import { useAuthStore } from '../store/authStore' -import KakaoOpenChatButton from '../components/common/KakaoOpenChatButton' -import { - FiClock, - FiChevronRight, - FiSearch, - FiCalendar, - FiUsers -} from 'react-icons/fi' -import Logo from '../assets/logo.png' -import GoogleLogo from '../assets/gogle.svg' -import { useUserStore } from '../store/userStore' -import { useState } from 'react' -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' +import { Link } from 'react-router-dom' +import { FiClock, FiChevronRight } from 'react-icons/fi' -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' - - const [characterName, setCharacterName] = useState('') - - const { - selectedServer, - setSelectedServer, - guildList, - searchGuildHandler, - addGuildList, - removeGuildList, - handleGuildKeyPress, - guildName, - setGuildName - } = useSearchGuild() - - const handleGuestLogin = async () => { - await storeLogin('', '', 'guest') - setCharacterOcid(guest.ocid) - - nav('/character') - } - - const handleMemberLogin = async () => { - try { - const userInfo = await userLogin() - if (userInfo) { - setUserInfo(userInfo) - setCharacterOcid(userInfo.ocid!) - if (userInfo?.nexonApiKey) { - nav('/character') - } else { - nav('/signup') - } - } - } catch { - alert('로그인에 실패했습니다.') - } - } - - const searchCharacterHandler = async () => { - if (characterName.trim() === '') { - alert('캐릭터 이름을 입력해주세요.') - return - } - - setSearchLoading(true) - try { - const { ocid } = await searchCharacterOcid(characterName.trim()) - - if (!ocid) { - alert('캐릭터를 찾을 수 없습니다.') - return - } - await storeLogin('', '', 'search') - setCharacterOcid(ocid) - nav(`/searchCharacter`) - } catch { - alert('캐릭터 검색에 실패했습니다.') - } finally { - setSearchLoading(false) - } - } - const onSearchGuild = async () => { - nav(`/searchGuild`) - searchGuildHandler() - } - - const recentNotices = [ - { - id: 1, - title: '서비스 이용 안내', - date: '2025.05.23' - }, - { - id: 2, - title: '메이플스토리 캘린더 업데이트 안내', - date: '2025.06.11' - }, - { - id: 3, - title: '다음 업데이트 예정 기능', - date: '2025.06' - }, - { - id: 4, - title: '메이플링크 비로그인 기능 업데이트 안내', - date: '2025.06.17' - }, - { - id: 5, - title: '챌린저스 서버 길드 검색 / 길드 관리 기능 업데이트 안내', - date: '2025.06.23' - } - ] +import HomeNavigation from '../components/home/HomeNavigation' +import HeroSection from '../components/home/HeroSection' +import GuildSearchSection from '../components/home/GuildSearchSection' +import CharacterSearchSection from '../components/home/CharacterSearchSection' +import FeatureShowcase from '../components/home/FeatureShowcase' +import { recentNotices } from '../data/notices' +const Home = () => { return (
- {/* 상단 네비게이션 */} - - +
- {/* 히어로 섹션 */} -
-
- 메이플링크 로고 -
- - - 메이플스토리 통합 관리 플랫폼 - -
-
-

- 메이플스토리를 더 스마트하게 -

-

- 캐릭터부터 길드까지, 한눈에 관리하세요 -

-
- - -
-
- - {/* 주요 기능 섹션 */} +
- {/* 길드 검색 */} -
-
-
-
- -
-

- 길드 검색 (최대 4개 검색 가능) -

-
-
-
- - 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" - /> - -
- -
-

검색할 길드 목록

-
- {guildList.map(guild => ( -
- {guild} - -
- ))} -
-
- - -
-
-
- - {/* 캐릭터 검색 */} -
-
-
-
- -
-

- 캐릭터 검색 -

-
-
- setCharacterName(e.target.value)} - className="w-full px-4 py-2.5 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm bg-white" - /> - -
-
-
- - {/* 체험하기 */} -
-
-
- -
-

체험하기

-
-
-
-

- 비로그인 이용 가능한 기능 -

-
- - 캐릭터 정보 조회 -
-
- - 길드 정보 조회 -
-
-
-

- 로그인 후 이용 가능한 기능 -

-
- - 캘린더로 일정 관리하기 -
-
- - 길드원 관리하기 -
-
- -
-
+ + +
- {/* 공지사항 섹션 */}
From 04b304ace97ba5375372ef2e66c76c5591971d1c Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 5 Sep 2025 22:13:24 +0900 Subject: [PATCH 2/6] =?UTF-8?q?[Style]=20=ED=99=88=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EB=AA=A8=EB=B0=94=EC=9D=BC=20=EB=B0=98=EC=9D=91?= =?UTF-8?q?=ED=98=95=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/GuildSearchSection.tsx | 110 +++++++++++---------- src/components/home/HeroSection.tsx | 21 ++-- src/components/home/HomeNavigation.tsx | 42 +++++++- src/pages/Home.tsx | 7 +- 4 files changed, 115 insertions(+), 65 deletions(-) diff --git a/src/components/home/GuildSearchSection.tsx b/src/components/home/GuildSearchSection.tsx index 6920b0d..a0e010d 100644 --- a/src/components/home/GuildSearchSection.tsx +++ b/src/components/home/GuildSearchSection.tsx @@ -24,22 +24,24 @@ const GuildSearchSection = () => { } return ( -
+
-
+
-

- 길드 검색 (최대 4개 검색 가능) +

+ 길드 검색 (최대 4개)

-
-
+ +
+ {/* 서버 선택과 입력 필드 */} +
- 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" - /> - -
-
-

검색할 길드 목록

-
- {guildList.map(guild => ( -
- {guild} - -
- ))} +
+ setGuildName(e.target.value)} + onKeyPress={handleGuildKeyPress} + className="flex-1 px-4 py-3 sm:py-2.5 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 bg-white" + /> +
+ {/* 길드 목록 */} + {guildList.length > 0 && ( +
+

검색할 길드 목록

+
+ {guildList.map(guild => ( +
+ {guild} + +
+ ))} +
+
+ )} +
diff --git a/src/components/home/HeroSection.tsx b/src/components/home/HeroSection.tsx index 24e0018..43e8e8d 100644 --- a/src/components/home/HeroSection.tsx +++ b/src/components/home/HeroSection.tsx @@ -36,35 +36,36 @@ const HeroSection = () => { } return ( -
+
메이플링크 로고 -
+
- + 메이플스토리 통합 관리 플랫폼
-

- 메이플스토리를 더 스마트하게 +

+ 메이플스토리를 +
더 스마트하게

-

+

캐릭터부터 길드까지, 한눈에 관리하세요

-
+
+ + {isMenuOpen && ( +
+
+ + setIsMenuOpen(false)}> + API 가이드 + + setIsMenuOpen(false)}> + FAQ + +
+
+ )}
) diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index e8db75a..88a3435 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -1,3 +1,4 @@ +// src/pages/Home.tsx import { Link } from 'react-router-dom' import { FiClock, FiChevronRight } from 'react-icons/fi' @@ -14,8 +15,12 @@ const Home = () => {
-
+ +
+
+ +
From 02010ef4347bcb95b239bb18de49c77831e078af Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 5 Sep 2025 22:19:25 +0900 Subject: [PATCH 3/6] =?UTF-8?q?[style]=20=EB=A0=88=EC=9D=B4=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=ED=8C=A8=EB=94=A9=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/layout/Layout.tsx | 4 ++-- src/pages/Home.tsx | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx index ebf2ee6..7b1949b 100644 --- a/src/components/layout/Layout.tsx +++ b/src/components/layout/Layout.tsx @@ -38,9 +38,9 @@ const Layout = ({ children, hide }: LayoutProps) => { } return ( -
+
{!hide &&
} -
+
{children}
{!hide &&