diff --git a/.gitignore b/.gitignore index d394ba57c..5ef6a5207 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ !.yarn/plugins !.yarn/releases !.yarn/versions -/test.http + # testing /coverage @@ -28,6 +28,7 @@ npm-debug.log* yarn-debug.log* yarn-error.log* +.pnpm-debug.log* # env files (can opt-in for committing if needed) .env* diff --git a/README.md b/README.md index 893f3bd57..e215bc4cc 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,36 @@ -# ๐Ÿผ ํŒ๋‹ค๋งˆ์ผ“ ํ”„๋กœ์ ํŠธ +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). -> _์ด ์ €์žฅ์†Œ๋Š” ํŒ๋‹ค๋งˆ์ผ“ ํ”„๋กœ์ ํŠธ์˜ ํ”„๋ก ํŠธ์—”๋“œ ์ฝ”๋“œ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ๋ฅผ ํด๋ก ํ•˜์—ฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ , ๊ฐ ๋ธŒ๋žœ์น˜์—์„œ ํ•ด๋‹น ์Šคํ”„๋ฆฐํŠธ ๋ฏธ์…˜์„ ์ˆ˜ํ–‰ํ•ด ์ฃผ์„ธ์š”!_ ๐Ÿ› ๏ธ +## Getting Started -## ์†Œ๊ฐœ +First, run the development server: -์•ˆ๋…•ํ•˜์„ธ์š”! ํŒ๋‹ค๋งˆ์ผ“ ํ”„๋กœ์ ํŠธ์— ์˜ค์‹  ๊ฒƒ์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค! ๐Ÿฅณ -ํŒ๋‹ค๋งˆ์ผ“์€ ๋”ฐ๋œปํ•œ ์ค‘๊ณ ๊ฑฐ๋ž˜๋ฅผ ์œ„ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ”Œ๋žซํผ์ด์—์š”. ์—ฌ๋Ÿฌ๋ถ„์€ ์ด๊ณณ์—์„œ ์ƒํ’ˆ์„ ๋“ฑ๋กํ•˜๊ณ , ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋“ค๊ณผ ์†Œํ†ตํ•˜๋ฉฐ, ์ž์œ ๋กญ๊ฒŒ ์ด์•ผ๊ธฐ๋ฅผ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์–ด์š”. ๋งค์ฃผ ์Šคํ”„๋ฆฐํŠธ ๋ฏธ์…˜์„ ํ†ตํ•ด ๊ธฐ๋Šฅ์„ ํ•˜๋‚˜์”ฉ ๋งŒ๋“ค์–ด ๊ฐ€๋ฉฐ ์„ฑ์žฅํ•ด ๋‚˜๊ฐ€๋Š” ์—ฌ์ •์„ ํ•จ๊ป˜ํ•ด์š”. ๐Ÿš€ +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` -![PandaMarket](https://github.com/user-attachments/assets/3784b99f-73c9-4349-a9a9-92b2a7563574) -_์œ„ ์ด๋ฏธ์ง€๋Š” ํŒ๋‹ค๋งˆ์ผ“์˜ ๋Œ€ํ‘œ ์ด๋ฏธ์ง€์ž…๋‹ˆ๋‹ค._ ๐Ÿ“ธ +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. -## ์Šคํ”„๋ฆฐํŠธ ๋ฏธ์…˜์ด๋ž€? ๐Ÿค” +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. -์Šคํ”„๋ฆฐํŠธ ๋ฏธ์…˜์€ **ํ•˜๋‚˜์˜ ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ธธ๊ฒŒ ์ง„ํ–‰ํ•˜๋ฉด์„œ, ๊ทธ ๊ณผ์ •์—์„œ ์ฃผ๊ธฐ์ ์œผ๋กœ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์‹œ์Šคํ…œ**์ด์—์š”. ๊ฐ ์Šคํ”„๋ฆฐํŠธ๋งˆ๋‹ค ๋ฐฐ์šด ์ด๋ก ์„ ์ ์šฉํ•ด ๋ณด๊ณ , **๋ฉ˜ํ† ๋‹˜๊ป˜ ์ฝ”๋“œ ๋ฆฌ๋ทฐ๋ฅผ ๋ฐ›์•„๊ฐ€๋ฉฐ ์‹ค๋ ฅ์„ ์‘ฅ์‘ฅ ํ‚ค์›Œ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ์ค‘์š”ํ•œ ๊ฐœ์ธ ๊ณผ์ œ**๋ž๋‹ˆ๋‹ค. ๐Ÿ’ช +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. -## ์ฃผ์š” ๊ธฐ๋Šฅ โœจ +## Learn More -1. **์ƒํ’ˆ ๋“ฑ๋ก**: ๋‚ด๊ฐ€ ๊ฐ€์ง„ ๋ฌผ๊ฑด์„ ์˜ฌ๋ฆฌ๊ณ , ์‚ฌ์ง„๊ณผ ์„ค๋ช…์„ ์ถ”๊ฐ€ํ•ด ์ง์ ‘ ํŒ๋งคํ•  ์ˆ˜ ์žˆ์–ด์š”! -2. **๋ฌธ์˜ ๋Œ“๊ธ€**: ์ƒํ’ˆ์— ๋Œ€ํ•œ ๊ถ๊ธˆํ•œ ์ ์ด๋‚˜ ์˜๊ฒฌ์„ ์ž์œ ๋กญ๊ฒŒ ๋‚จ๊ธธ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค. ๐Ÿ“ -3. **์ž์œ ๊ฒŒ์‹œํŒ**: ๋‹ค์–‘ํ•œ ์ฃผ์ œ๋กœ ์นœ๊ตฌ๋“ค๊ณผ ์ด์•ผ๊ธฐ๋ฅผ ๋‚˜๋ˆ„๊ณ , ์ •๋ณด๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ณต๊ฐ„์ด์—์š”! ๐Ÿ—ฃ๏ธ +To learn more about Next.js, take a look at the following resources: -## ํ”„๋กœ์ ํŠธ ๋ธŒ๋žœ์น˜ ๊ตฌ์กฐ ๐Ÿ—๏ธ +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. -ํ”„๋กœ์ ํŠธ๋Š” ๋‹จ๊ณ„๋ณ„๋กœ ๋‚˜๋‰˜์–ด ์žˆ๊ณ , ๊ฐ ์Šคํ”„๋ฆฐํŠธ ๋ฏธ์…˜์— ๋งž๋Š” ๋ธŒ๋žœ์น˜๊ฐ€ ์žˆ์–ด์š”. ๊ฐ ๋ธŒ๋žœ์น˜๋ฅผ ํ†ตํ•ด ์ฒด๊ณ„์ ์œผ๋กœ ๊ฐœ๋ฐœํ•˜๋ฉฐ ํ•™์Šตํ•  ์ˆ˜ ์žˆ์–ด์š”. ๐ŸŽฏ +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! -### ๋ธŒ๋žœ์น˜ ์„ค๋ช… +## Deploy on Vercel -1. **basic (part1): ์Šคํ”„๋ฆฐํŠธ ๋ฏธ์…˜ 1 ~ 4 FE ์š”๊ตฌ์‚ฌํ•ญ** +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - - ๊ธฐ๋ณธ์ ์ธ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ์œ„ํ•œ ์ดˆ๊ธฐ ๋ธŒ๋žœ์น˜์ž…๋‹ˆ๋‹ค. HTML, CSS, JavaScript ๋“ฑ์„ ์‚ฌ์šฉํ•ด ๊ธฐ๋ณธ์„ ๋‹ค์ง‘๋‹ˆ๋‹ค. - - **์Šคํ”„๋ฆฐํŠธ ๋ฏธ์…˜ 1๋ถ€ํ„ฐ 4๊นŒ์ง€**์˜ ํ”„๋ก ํŠธ์—”๋“œ ๋‚ด์šฉ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์–ด์š”. - -2. **react (part2): ์Šคํ”„๋ฆฐํŠธ ๋ฏธ์…˜ 5 ~ 7 FE ์š”๊ตฌ์‚ฌํ•ญ** - - - React ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด ํ”„๋ก ํŠธ์—”๋“œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ธŒ๋žœ์น˜์ž…๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ์•„ํ‚คํ…์ฒ˜์™€ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ๋ฐฐ์›๋‹ˆ๋‹ค. - - **์Šคํ”„๋ฆฐํŠธ ๋ฏธ์…˜ 5๋ถ€ํ„ฐ 7๊นŒ์ง€, ๊ทธ ์ดํ›„**์˜ ํ”„๋ก ํŠธ์—”๋“œ ๋‚ด์šฉ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์–ด์š”. - - ๋งŒ์•ฝ ์Šคํ”„๋ฆฐํŠธ ๋ฏธ์…˜ 9๋ถ€ํ„ฐ ํ”„๋ก ํŠธ์—”๋“œ ์ฝ”๋“œ๋ฅผ Next๊ฐ€ ์•„๋‹Œ React๋กœ ๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด react ๋ธŒ๋žœ์น˜๋ฅผ ์‚ฌ์šฉํ•ด์š”. - -3. **next (part3,4): ์Šคํ”„๋ฆฐํŠธ ๋ฏธ์…˜ 8 FE ์š”๊ตฌ์‚ฌํ•ญ~** - - - Next.js๋ฅผ ์‚ฌ์šฉํ•ด ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง(SSR)๊ณผ ์ •์  ์‚ฌ์ดํŠธ ์ƒ์„ฑ(SSG) ๋“ฑ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. - - **์Šคํ”„๋ฆฐํŠธ ๋ฏธ์…˜ 8๋ถ€ํ„ฐ** ์‹œ์ž‘ํ•˜๋Š” ํ”„๋ก ํŠธ์—”๋“œ ๋‚ด์šฉ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์–ด์š”. - - ๋งŒ์•ฝ ์Šคํ”„๋ฆฐํŠธ ๋ฏธ์…˜ 9๋ถ€ํ„ฐ ํ”„๋ก ํŠธ์—”๋“œ ์ฝ”๋“œ๋ฅผ React๊ฐ€ ์•„๋‹Œ Next๋กœ ๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด next ๋ธŒ๋žœ์น˜๋ฅผ ์‚ฌ์šฉํ•ด์š”. - -> _์Šคํ”„๋ฆฐํŠธ ๋ฏธ์…˜ ๋‚ด ๋ฐฑ์—”๋“œ ์š”๊ตฌ์‚ฌํ•ญ์€ [๋ฐฑ์—”๋“œ ๋ ˆํฌ์ง€ํ† ๋ฆฌ](https://github.com/codeit-sprint-fullstack/3-sprint-mission-be)์˜ ๋ธŒ๋žœ์น˜์—์„œ ๊ด€๋ฆฌํ•ด์ฃผ์„ธ์š”_ - ---- - -๋ณธ ํ”„๋กœ์ ํŠธ๋Š” [์ฝ”๋“œ์ž‡](https://www.codeit.kr)์˜ ์†Œ์œ ์ด๋ฉฐ, ๊ต์œก ๋ชฉ์ ์œผ๋กœ๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ยฉ 2024 Codeit. All rights reserved. +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/components/ArticleCommentDropDown.js b/components/ArticleCommentDropDown.js deleted file mode 100644 index 1b5cd9082..000000000 --- a/components/ArticleCommentDropDown.js +++ /dev/null @@ -1,96 +0,0 @@ -import { useState, useRef, useEffect } from 'react'; -import styles from '@/css/Dropdown.module.css'; -import Image from 'next/image'; -import instance from '@/lib/instance'; - -export default function ArticleCommentDropDown({ id, onCommentAdded }) { - const [isOpen, setIsOpen] = useState(false); - const [isEditing, setIsEditing] = useState(false); - const [editContent, setEditContent] = useState('๋Œ“๊ธ€ ์ˆ˜์ •'); - const dropdownRef = useRef(null); - - - const toggleDropdown = () => { - setIsOpen(!isOpen); - }; - - const handlePatch = () => { - const accessToken = localStorage.getItem('accessToken'); - - try { - instance.patch(`/comments/${id}`, { - content: editContent, - }, { - headers: { - Authorization: `Bearer ${accessToken}`, - } - }); - alert('๋Œ“๊ธ€์ด ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค!'); - setIsEditing(!isEditing); - setIsOpen(!isOpen); - onCommentAdded(); - } catch (error) { - console.error('๋Œ“๊ธ€ ์ˆ˜์ • ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ:', error); - } - } - - const handleDelete = () => { - const accessToken = localStorage.getItem('accessToken'); - - instance.delete(`/comments/${id}`, { - headers: { - Authorization: `Bearer ${accessToken}`, - } - }) - .then((response) => { - alert("๋Œ“๊ธ€์ด ์‚ญ์ œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!"); - onCommentAdded(); - setIsOpen(!isOpen); - }).catch((error) => { - console.error(error); - }); - }; - - useEffect(() => { - const handleClickOutside = (e) => { - if (dropdownRef.current && !dropdownRef.current.contains(e.target)) { - setIsOpen(false); - } - }; - - window.addEventListener('click', handleClickOutside); - return () => { - window.removeEventListener('click', handleClickOutside); - }; - }, []); - - return ( -
- - {isOpen && ( - - )} -
- ); -} \ No newline at end of file diff --git a/components/ArticleDetail.js b/components/ArticleDetail.js deleted file mode 100644 index aa1c71888..000000000 --- a/components/ArticleDetail.js +++ /dev/null @@ -1,145 +0,0 @@ -import styles from '@/css/articleDetail.module.css'; -import Image from 'next/image'; -import dayjs from "dayjs"; -import { useRouter } from 'next/router'; -import { useState } from 'react'; -import instance from '@/lib/instance'; -import ArticleDropDown from './ArticleDropDown'; -import ArticleCommentDropDown from './ArticleCommentDropDown'; - -export default function ArticleDetail({ article, onCommentAdded }) { - const [content, setContent] = useState(''); - const router = useRouter(); - - const handleClick = () => { - router.push(`/`); - }; - - const handlePostSubmit = () => { - if (!content) { - alert('๋‚ด์šฉ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”!'); - } - if (content) { - const accessToken = localStorage.getItem('accessToken'); - instance.post(`/articles/${article.id}/comments`, { - content, - }, { - headers: { - Authorization: `Bearer ${accessToken}`, - } - }).then((response) => { - alert("๋Œ“๊ธ€์ด ๋“ฑ๋ก๋˜์—ˆ์Šต๋‹ˆ๋‹ค!"); - onCommentAdded(); - setContent(''); - }).catch((error) => { - console.error(error); - }); - } - }; - - const handleKeyDown = (e) => { - if (e.key === 'Enter') { - handlePostSubmit(); - } - }; - - return ( -
-
-
- {article.title} -
- -
-
-
-
- User -
-
{article.writer.nickname}
-
{dayjs(article.createdAt).format('YYYY. MM. DD')}
-
-
-
- heart -
-
{article.likeCount}
-
-
- -
- {article.content} -
- -
๋Œ“๊ธ€ ๋‹ฌ๊ธฐ
-