Skip to content

Commit

Permalink
feat : 유저 검색 페이지 마이그레이션
Browse files Browse the repository at this point in the history
- api 호출 방식 변경 axios → fetch
- useNavigate → useRouter
- react-router-dom의 URL 파라미터 라우팅 방식 → Next.js dynamic routing 방식
- useParams → Next.js dynamic routing
- img 태그 → 'next/image’의 Image 태그로 변경
  • Loading branch information
Yujin-Baek committed Sep 30, 2023
1 parent 1f747c6 commit 2aea10d
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 1 deletion.
4 changes: 3 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
"format:fix": "prettier --write --ignore-path .gitignore ."
},
"dependencies": {
"@tanstack/react-query": "^4.35.3",
"@hookform/resolvers": "^3.3.1",
"@tanstack/react-query": "^4.35.3",
"@types/node": "20.6.3",
"@types/react": "18.2.22",
"@types/react-dom": "18.2.7",
"@types/uuid": "^9.0.4",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"autoprefixer": "10.4.15",
Expand All @@ -36,6 +37,7 @@
"swiper": "^10.3.0",
"tailwindcss": "3.3.3",
"typescript": "5.2.2",
"uuid": "^9.0.1",
"yup": "^1.3.0"
},
"devDependencies": {
Expand Down
138 changes: 138 additions & 0 deletions frontend/src/app/(search)/search-user/[nickname]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
'use client'

import { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation'
import { v4 as uuidv4 } from 'uuid'
import Image from 'next/image'

import WriteIcon from '../../../../../public/images/svg/pencil-square.svg'
import ProfileIcon from '../../../../../public/images/svg/profileIcon.svg'
// TODO: import NavBar from '../../../components/general/NavBar'
import Banner from '../../../../components/main/Banner'

type DataObject = {
nickname: string
email: string
}

type ParamsType = {
params: {
nickname: string
}
}

export default function SearchUserPage({ params }: ParamsType) {
const [data, setData] = useState<DataObject[]>([]) // 데이터를 담을 state 선언
const [hoveredEmail, setHoveredEmail] = useState('')
const router = useRouter()
const accessToken =
typeof window !== 'undefined' ? sessionStorage.getItem('accessToken') : null
const persistToken =
typeof window !== 'undefined' ? localStorage.getItem('persistToken') : null

function handleMouseEnter(email: string) {
setHoveredEmail(email)
}

function handleMouseLeave() {
setHoveredEmail('')
}

function toWrite() {
router.push('/write')
}

async function getData() {
const res = await fetch(
`${process.env.NEXT_PUBLIC_BASE_URL}/members?nickname=${params.nickname}`,
{
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken || persistToken}`,
},
},
)

const resData = await res.json()

if (resData.data.length === 0) {
setData([{ nickname: '검색 결과가 없습니다.', email: '' }])
} else {
setData(resData.data)
}

if (!res.ok) {
alert('검색 결과가 없습니다.')
router.push('/')
throw new Error('검색 결과가 없습니다.')
}
}

useEffect(() => {
getData()
}, [params])

return (
<div className="relative h-auto min-h-screen w-screen bg-gray-50">
{/* TODO: <NavBar /> */}
<Banner />

<div>
{/* 프로젝트 공유 버튼 */}
<button
className="fixed bottom-10 right-10 z-10 my-auto mb-2 flex shrink-0 flex-row items-center rounded-full
bg-graphyblue px-4 py-1 pt-3 pb-3 font-semibold text-slate-50 drop-shadow-md
sm:invisible"
onClick={() => toWrite()}
aria-label="toWritePage"
type="button"
>
<Image
className="mr-2 h-5 w-5"
src={WriteIcon}
alt="WriteIcon"
quality={50}
/>
<span className="shrink-0 font-semibold">프로젝트 공유</span>
</button>

<div className="mx-10 border-b-2 border-b-neutral-300 pt-0 font-ng-b text-2xl sm:mx-28 sm:mb-5 sm:pt-5">
{/* All */}
</div>
<div>
<div className="ml-0 flex flex-wrap justify-center min-[680px]:ml-10 min-[680px]:justify-start">
{data.map((item) => (
<div key={uuidv4()}>
{item.nickname === '검색 결과가 없습니다.' ? (
<div className="mx-3 mt-9 flex min-[680px]:mx-0 min-[680px]:ml-16 ">
<span>{item.nickname}</span>
</div>
) : (
<div
className="mx-3 mt-9 flex min-[680px]:mx-0 min-[680px]:ml-16 "
onMouseEnter={() => handleMouseEnter(item.email)}
onMouseLeave={handleMouseLeave}
>
<Image
className="mr-2 h-6 w-6"
src={ProfileIcon}
alt="ProfileIcon"
/>
<span className="relative">
{item.nickname}
{hoveredEmail === item.email && (
<span className="absolute -top-5 -left-0.5 bg-gray-200 px-1 text-xs">
{item.email}
</span>
)}
</span>
</div>
)}
</div>
))}
</div>
</div>
</div>
</div>
)
}
Empty file.
10 changes: 10 additions & 0 deletions frontend/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,11 @@
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.3.tgz#9a726e116beb26c24f1ccd6850201e1246122e04"
integrity sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==

"@types/uuid@^9.0.4":
version "9.0.4"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.4.tgz#e884a59338da907bda8d2ed03e01c5c49d036f1c"
integrity sha512-zAuJWQflfx6dYJM62vna+Sn5aeSWhh3OB+wfUEACNcqUSc0AGc5JKl+ycL1vrH7frGTXhJchYjE1Hak8L819dA==

"@typescript-eslint/eslint-plugin@^6.0.0":
version "6.7.3"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.3.tgz#d98046e9f7102d49a93d944d413c6055c47fafd7"
Expand Down Expand Up @@ -2636,6 +2641,11 @@ util-deprecate@^1.0.2:
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==

uuid@^9.0.1:
version "9.0.1"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==

[email protected]:
version "2.4.0"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d"
Expand Down

0 comments on commit 2aea10d

Please sign in to comment.