Skip to content

Commit

Permalink
Merge pull request #3 from YerangPark/dev
Browse files Browse the repository at this point in the history
fix: API URL 버그 수정
  • Loading branch information
YerangPark authored Oct 15, 2024
2 parents a887abd + 5a915d5 commit 617d4f6
Show file tree
Hide file tree
Showing 23 changed files with 1,958 additions and 131 deletions.
1,776 changes: 1,700 additions & 76 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
"@reduxjs/toolkit": "^2.2.7",
"date-fns": "^4.1.0",
"framer-motion": "^11.9.0",
"next": "14.2.5",
"next": "^14.2.15",
"react": "^18",
"react-dom": "^18",
"react-icons": "^5.3.0",
"react-redux": "^9.1.2"
"react-markdown": "^9.0.1",
"react-redux": "^9.1.2",
"rehype-raw": "^7.0.0",
"remark-gfm": "^4.0.0"
},
"devDependencies": {
"@types/node": "^20",
Expand Down
15 changes: 15 additions & 0 deletions src/app/[username]/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use client'

import PortfolioViewPage from '@/components/templates/PortfolioViewPage'
import { useParams } from 'next/navigation'

export default function Page() {
const params = useParams()
if (Array.isArray(params.id) || !params.id || Array.isArray(params.username) || !params.username) {
return <div>올바르지 않은 접근입니다.</div>
}
const { username } = params
const id = parseInt(params.id, 10)

return <PortfolioViewPage username={username} id={id} isPublic />
}
12 changes: 0 additions & 12 deletions src/app/client-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { useEffect, useRef } from 'react'
import { Provider, useDispatch } from 'react-redux'
import { fetchSkills } from '@/features/skill/skillSlice'
import store, { AppDispatch } from '@/store'
import isTokenExpired from '@/utils/TokenExpiredChecker'
import { useRouter } from 'next/navigation'
import theme from '../theme'

function ClientComponentWrapper({ children }: { children: React.ReactNode }) {
Expand All @@ -24,16 +22,6 @@ function ClientComponentWrapper({ children }: { children: React.ReactNode }) {
}

export default function ClientLayout({ children }: { children: React.ReactNode }) {
const router = useRouter()

useEffect(() => {
const token = localStorage.getItem('token')
if (!token || isTokenExpired(token)) {
localStorage.removeItem('token')
router.push('/')
}
}, [router])

return (
<Provider store={store}>
<ClientComponentWrapper>
Expand Down
15 changes: 15 additions & 0 deletions src/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
'use client'

import DashboardPage from '@/components/templates/DashboardPage'
import isTokenExpired from '@/utils/TokenExpiredChecker'
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'

export default function Page() {
const router = useRouter()

useEffect(() => {
const token = localStorage.getItem('token')
if (!token || isTokenExpired(token)) {
localStorage.removeItem('token')
router.push('/')
}
}, [router])

return <DashboardPage />
}
9 changes: 9 additions & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,13 @@ a {
background-color: #f8f9fa;
text-align: center;
box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.1);
}

.markdown {
max-width: 100%;
overflow-x: auto;
}

.markdown > * {
all: revert;
}
15 changes: 15 additions & 0 deletions src/app/guestbook/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
'use client'

import GuestbookPage from '@/components/templates/GuestbookPage'
import isTokenExpired from '@/utils/TokenExpiredChecker'
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'

export default function Page() {
const router = useRouter()

useEffect(() => {
const token = localStorage.getItem('token')
if (!token || isTokenExpired(token)) {
localStorage.removeItem('token')
router.push('/')
}
}, [router])

return <GuestbookPage />
}
14 changes: 13 additions & 1 deletion src/app/portfolio/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
'use client'

import PortfolioViewPage from '@/components/templates/PortfolioViewPage'
import { useParams } from 'next/navigation'
import { useParams, useRouter } from 'next/navigation'
import isTokenExpired from '@/utils/TokenExpiredChecker'
import { useEffect } from 'react'

export default function Page() {
const router = useRouter()

useEffect(() => {
const token = localStorage.getItem('token')
if (!token || isTokenExpired(token)) {
localStorage.removeItem('token')
router.push('/')
}
}, [router])

const params = useParams()
if (Array.isArray(params.id) || !params.id) {
return <div>올바르지 않은 접근입니다.</div>
Expand Down
15 changes: 15 additions & 0 deletions src/app/portfolio/create/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
'use client'

import PortfolioFormPage from '@/components/templates/PortfolioFormPage'
import isTokenExpired from '@/utils/TokenExpiredChecker'
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'

export default function Page() {
const router = useRouter()

useEffect(() => {
const token = localStorage.getItem('token')
if (!token || isTokenExpired(token)) {
localStorage.removeItem('token')
router.push('/')
}
}, [router])

return <PortfolioFormPage />
}
14 changes: 13 additions & 1 deletion src/app/portfolio/edit/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
'use client'

import PortfolioFormPage from '@/components/templates/PortfolioFormPage'
import { useParams } from 'next/navigation'
import { useParams, useRouter } from 'next/navigation'
import isTokenExpired from '@/utils/TokenExpiredChecker'
import { useEffect } from 'react'

export default function Page() {
const router = useRouter()

useEffect(() => {
const token = localStorage.getItem('token')
if (!token || isTokenExpired(token)) {
localStorage.removeItem('token')
router.push('/')
}
}, [router])

const params = useParams()
if (Array.isArray(params.id) || !params.id) {
return <div>올바르지 않은 접근입니다.</div>
Expand Down
7 changes: 1 addition & 6 deletions src/components/organisms/DashboardContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ import { useRouter } from 'next/navigation'
const DashboardContent: React.FC<DashboardProps> = ({ data, onHover, openDeletePortfolioModal, handleExport }) => {
const router = useRouter()

const copyToClipboard = (text: string) => {
navigator.clipboard.writeText(text)
}

return (
<Box display="flex" flexWrap="wrap" gap={4} mt="4">
{data &&
Expand Down Expand Up @@ -87,8 +83,7 @@ const DashboardContent: React.FC<DashboardProps> = ({ data, onHover, openDeleteP
variant="solid"
_hover={{ bg: 'blue.600' }}
onClick={() => {
handleExport()
copyToClipboard('복사할 텍스트')
handleExport(portfolio.id)
}}
/>
</Box>
Expand Down
2 changes: 1 addition & 1 deletion src/components/organisms/DeletePortfolioModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface DeletePortfolioModalProps {
onDeleteComplete: () => void
}

const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://yrpark.duckdns.org:8080'

const DeletePortfolioModal: React.FC<DeletePortfolioModalProps> = ({
isOpen,
Expand Down
2 changes: 1 addition & 1 deletion src/components/organisms/FindIdModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ interface FindIdModalProps {
openLoginModal: () => void
}

const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://yrpark.duckdns.org:8080'

const shake = keyframes`
10%, 90% {
Expand Down
2 changes: 1 addition & 1 deletion src/components/organisms/FindPasswordModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ interface FindPasswordModalProps {
openLoginModal: () => void
}

const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://yrpark.duckdns.org:8080'

const shake = keyframes`
10%, 90% {
Expand Down
2 changes: 1 addition & 1 deletion src/components/organisms/LoginModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ interface SuccessResponse {

type LoginResponse = SuccessResponse | ErrorResponse

const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://yrpark.duckdns.org:8080'

const shake = keyframes`
10%, 90% {
Expand Down
57 changes: 57 additions & 0 deletions src/components/organisms/MarkdownModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React, { useState, useEffect } from 'react'
import ReactMarkdown from 'react-markdown'
// eslint-disable-next-line import/no-extraneous-dependencies
import rehypeRaw from 'rehype-raw'
// eslint-disable-next-line import/no-extraneous-dependencies
import remarkGfm from 'remark-gfm'
import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalBody, ModalCloseButton } from '@chakra-ui/react'

interface MarkdownModalProps {
isOpen: boolean
onClose: () => void
mdFilePath: string // .md 파일의 경로
}

const fetchMarkdownContent = async (mdFilePath: string): Promise<string> => {
try {
const response = await fetch(mdFilePath)
const content = await response.text()
return content
} catch (error) {
console.error('Markdown 파일을 불러오는 중 오류 발생:', error)
return ''
}
}

const MarkdownModal: React.FC<MarkdownModalProps> = ({ isOpen, onClose, mdFilePath }) => {
const [markdownContent, setMarkdownContent] = useState<string>('')

console.log(`mdFilePath : ${mdFilePath}`)
// .md 파일 읽어오기
useEffect(() => {
if (isOpen && mdFilePath) {
fetchMarkdownContent(mdFilePath).then((content) => {
setMarkdownContent(content)
})
}
}, [isOpen, mdFilePath])

return (
<Modal isOpen={isOpen} onClose={onClose} size="xl">
<ModalOverlay />
<ModalContent>
<ModalHeader>Markdown 내용 보기</ModalHeader>
<ModalCloseButton />
<ModalBody>
<div className="markdown">
<ReactMarkdown rehypePlugins={[rehypeRaw]} remarkPlugins={[remarkGfm]}>
{markdownContent}
</ReactMarkdown>
</div>
</ModalBody>
</ModalContent>
</Modal>
)
}

export default MarkdownModal
2 changes: 1 addition & 1 deletion src/components/organisms/SignupModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ interface SignupModalProps {
openLoginModal: () => void
}

const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://yrpark.duckdns.org:8080'

const SignupModal: React.FC<SignupModalProps> = ({ isOpen, onClose, openLoginModal }) => {
// 사용자 입력 상태 관리
Expand Down
2 changes: 1 addition & 1 deletion src/components/templates/AccountPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import AccountForm from '../organisms/AccountForm'
import Button from '../atoms/Button'
import FadeNotification from '../organisms/FadeNotification'

const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://yrpark.duckdns.org:8080'

const AccountPage: React.FC = () => {
const router = useRouter()
Expand Down
45 changes: 41 additions & 4 deletions src/components/templates/DashboardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import DeletePortfolioModal from '../organisms/DeletePortfolioModal'
import FadeNotification from '../organisms/FadeNotification'
import Button from '../atoms/Button'

const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://yrpark.duckdns.org:8080'

const DashboardPage: React.FC = () => {
const router = useRouter()
Expand All @@ -23,6 +23,31 @@ const DashboardPage: React.FC = () => {
const [selectedPortfolio, setSelectedPortfolio] = useState({ id: 0, file_name: '' })
const [notificationMessage, setNotificationMessage] = useState<string>('')
const [showNotification, setShowNotification] = useState(false)
const [username, setUsername] = useState('')

const getUserInfo = async () => {
try {
const response = await fetch(`${apiUrl}/api/user`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${localStorage.getItem('token')}`,
},
mode: 'cors',
})

const res = await response.json()
if (res.success) {
setUsername(res.data.username)
} else if (response.status === 400 && res.error.code === 'USER_NOT_FOUND') {
console.error('유저를 찾을 수 없습니다.')
} else {
console.error('유저 정보 조회에 실패했습니다.')
}
} catch (error) {
console.error('에러가 발생했습니다.')
}
}

const fetchPortfolioList = async () => {
const token = localStorage.getItem('token')
Expand Down Expand Up @@ -78,6 +103,7 @@ const DashboardPage: React.FC = () => {

useEffect(() => {
fetchPortfolioList()
getUserInfo()
}, [])

return (
Expand Down Expand Up @@ -106,9 +132,20 @@ const DashboardPage: React.FC = () => {
data={portfolios}
onHover={setSelectedPortfolio}
openDeletePortfolioModal={openDeletePortfolioModal}
handleExport={() => {
setNotificationMessage('내보내기 링크가 복사되었습니다.')
setShowNotification(true)
handleExport={(portfolioId) => {
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || 'http://yrpark.duckdns.org'
const publicUrl = `${baseUrl}/${username}/${portfolioId}`
navigator.clipboard
.writeText(publicUrl)
.then(() => {
setNotificationMessage('내보내기 링크가 복사되었습니다.')
setShowNotification(true)
})
.catch((err) => {
console.error('링크 복사 중 오류가 발생했습니다:', err)
setNotificationMessage('링크 복사 중 오류가 발생했습니다.')
setShowNotification(true)
})
}}
/>
) : (
Expand Down
2 changes: 1 addition & 1 deletion src/components/templates/PortfolioFormPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import PortfolioInputForm from '../organisms/PortfolioInputForm'
import PortfolioInputFooter from '../molecules/PortfolioInputFooter'
import ProjectInputForm from '../organisms/ProjectInputForm'

const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://yrpark.duckdns.org:8080'

interface PortfolioFormPageProps {
id?: number
Expand Down
Loading

0 comments on commit 617d4f6

Please sign in to comment.