-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from YerangPark/dev
Dev 브랜치 머지 (반응형 웹 구현)
- Loading branch information
Showing
24 changed files
with
365 additions
and
235 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,83 @@ | ||
'use client' | ||
|
||
import PortfolioViewPage from '@/components/templates/PortfolioViewPage' | ||
import { useParams } from 'next/navigation' | ||
import { Portfolio } from '@/types/data' | ||
|
||
export default function Page() { | ||
const params = useParams() | ||
if (Array.isArray(params.id) || !params.id || Array.isArray(params.username) || !params.username) { | ||
export default async function Page({ params }: { params: { username: string; id: string } }) { | ||
const { username, id } = params | ||
if (Array.isArray(id) || !id || Array.isArray(username) || !username) { | ||
return <div>올바르지 않은 접근입니다.</div> | ||
} | ||
const { username } = params | ||
const id = parseInt(params.id, 10) | ||
|
||
return <PortfolioViewPage username={username} id={id} isPublic /> | ||
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://yrpark.duckdns.org:8080' | ||
|
||
const getPortfolioData = async (): Promise<Portfolio | null> => { | ||
const url = `${apiUrl}/api/${username}/${id}` | ||
const headers: Record<string, string> = {} | ||
|
||
const response = await fetch(url, { | ||
method: 'GET', | ||
headers, | ||
}) | ||
|
||
const res = await response.json() | ||
if (response.ok) { | ||
const portfolio = res.data | ||
|
||
// API에서 얻은 데이터를 포트폴리오 state에 저장 | ||
return { | ||
portfolioName: portfolio.file_name, | ||
title: portfolio.title, | ||
description: portfolio.description, | ||
githubLink: portfolio.github_link, | ||
blogLink: portfolio.blog_link, | ||
image: `${apiUrl}/uploads/${portfolio.image}`, | ||
skills: portfolio.portfolioSkills.map((skill: any) => skill.skill_id), | ||
// eslint-disable-next-line no-underscore-dangle | ||
projects: portfolio.__projects__.map((project: any) => ({ | ||
id: project.id, | ||
name: project.name, | ||
description: project.description, | ||
githubLink: project.github_link, | ||
siteLink: project.site_link, | ||
startDate: project.start_date ? project.start_date.split('-').slice(0, 2).join('-') : '', | ||
endDate: project.end_date ? project.end_date.split('-').slice(0, 2).join('-') : '', | ||
image: project.image ? `${apiUrl}/uploads/${project.image}` : null, | ||
readmeFile: project.readme_file ? `${apiUrl}/uploads/${project.readme_file}` : null, | ||
skills: project.projectSkills.map((skill: any) => skill.skill_id), | ||
})), | ||
} | ||
} | ||
console.error('포트폴리오 불러오기 실패:', res.message) | ||
return null | ||
} | ||
|
||
const getUserData = async () => { | ||
const url = `${apiUrl}/api/user/public/${username}` | ||
const headers: Record<string, string> = {} | ||
|
||
const response = await fetch(url, { | ||
method: 'GET', | ||
headers, | ||
}) | ||
|
||
const res = await response.json() | ||
if (response.ok) { | ||
const user = res.data | ||
return { | ||
name: user.name, | ||
email: user.email, | ||
birthdate: user.birthdate, | ||
} | ||
} | ||
console.error('포트폴리오 불러오기 실패:', res.message) | ||
return null | ||
} | ||
|
||
const portfolioData = await getPortfolioData() | ||
const userData = await getUserData() | ||
|
||
if (!portfolioData || !userData) { | ||
return <div>포트폴리오 데이터를 불러올 수 없습니다.</div> | ||
} | ||
|
||
return <PortfolioViewPage portfolioData={portfolioData} userData={userData} /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,114 @@ | ||
'use client' | ||
|
||
import { useEffect, useState } from 'react' | ||
import { useRouter } from 'next/navigation' | ||
import PortfolioViewPage from '@/components/templates/PortfolioViewPage' | ||
import { useParams, useRouter } from 'next/navigation' | ||
import isTokenExpired from '@/utils/TokenExpiredChecker' | ||
import { useEffect } from 'react' | ||
|
||
export default function Page() { | ||
export default function Page({ params }: { params: { id: string } }) { | ||
const { id } = params | ||
const router = useRouter() | ||
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://yrpark.duckdns.org:8080' | ||
|
||
const [portfolioData, setPortfolioData] = useState<any>(null) | ||
const [userData, setUserData] = useState<any>(null) | ||
const [loading, setLoading] = useState(true) | ||
|
||
useEffect(() => { | ||
const token = localStorage.getItem('token') | ||
if (!token || isTokenExpired(token)) { | ||
localStorage.removeItem('token') | ||
router.push('/') | ||
return | ||
} | ||
|
||
const fetchPortfolioData = async () => { | ||
const url = `${apiUrl}/api/portfolio/${id}` | ||
const headers: Record<string, string> = {} | ||
headers.Authorization = `Bearer ${token}` | ||
|
||
const response = await fetch(url, { | ||
method: 'GET', | ||
headers, | ||
}) | ||
|
||
const res = await response.json() | ||
if (response.status === 401) { | ||
localStorage.removeItem('token') | ||
router.push('/') | ||
return | ||
} | ||
|
||
if (response.ok) { | ||
const portfolio = res.data | ||
setPortfolioData({ | ||
portfolioName: portfolio.file_name, | ||
title: portfolio.title, | ||
description: portfolio.description, | ||
githubLink: portfolio.github_link, | ||
blogLink: portfolio.blog_link, | ||
image: `${apiUrl}/uploads/${portfolio.image}`, | ||
skills: portfolio.portfolioSkills.map((skill: any) => skill.skill_id), | ||
// eslint-disable-next-line no-underscore-dangle | ||
projects: portfolio.__projects__.map((project: any) => ({ | ||
id: project.id, | ||
name: project.name, | ||
description: project.description, | ||
githubLink: project.github_link, | ||
siteLink: project.site_link, | ||
startDate: project.start_date ? project.start_date.split('-').slice(0, 2).join('-') : '', | ||
endDate: project.end_date ? project.end_date.split('-').slice(0, 2).join('-') : '', | ||
image: project.image ? `${apiUrl}/uploads/${project.image}` : null, | ||
readmeFile: project.readme_file ? `${apiUrl}/uploads/${project.readme_file}` : null, | ||
skills: project.projectSkills.map((skill: any) => skill.skill_id), | ||
})), | ||
}) | ||
} | ||
} | ||
|
||
const fetchUserData = async () => { | ||
const url = `${apiUrl}/api/user` | ||
const headers: Record<string, string> = {} | ||
headers.Authorization = `Bearer ${token}` | ||
|
||
const response = await fetch(url, { | ||
method: 'GET', | ||
headers, | ||
}) | ||
|
||
const res = await response.json() | ||
if (response.status === 401) { | ||
localStorage.removeItem('token') | ||
router.push('/') | ||
return | ||
} | ||
|
||
if (response.ok) { | ||
const user = res.data | ||
setUserData({ | ||
name: user.name, | ||
email: user.email, | ||
birthdate: user.birthdate, | ||
}) | ||
} | ||
} | ||
|
||
const fetchData = async () => { | ||
await fetchPortfolioData() | ||
await fetchUserData() | ||
setLoading(false) // 데이터가 모두 로드되면 로딩을 종료합니다. | ||
} | ||
}, [router]) | ||
|
||
const params = useParams() | ||
if (Array.isArray(params.id) || !params.id) { | ||
return <div>올바르지 않은 접근입니다.</div> | ||
fetchData() | ||
}, [id, router, apiUrl]) | ||
|
||
if (loading) { | ||
return <div>Loading...</div> | ||
} | ||
|
||
if (!portfolioData || !userData) { | ||
return <div>포트폴리오 데이터를 불러올 수 없습니다.</div> | ||
} | ||
const id = parseInt(params.id, 10) | ||
|
||
return <PortfolioViewPage id={id} /> | ||
return <PortfolioViewPage portfolioData={portfolioData} userData={userData} /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.