Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: API URL 버그 수정 #3

Merged
merged 3 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading