-
Notifications
You must be signed in to change notification settings - Fork 37
[윤혜림] Sprint9 #309
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
Merged
withyj-codeit
merged 36 commits into
codeit-bootcamp-frontend:Next-윤혜림
from
y5037:Next-윤혜림-sprint9
Jan 31, 2025
The head ref may contain hidden characters: "Next-\uC724\uD61C\uB9BC-sprint9"
Merged
[윤혜림] Sprint9 #309
Changes from all commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
69b09ad
chore: project name 변경
y5037 93f3227
feat: Vite-react-app에서 next로 마이그레이션 완료
y5037 35d034d
refactor(mentor):types 파일은 타입스크립트 파일에서 import 하여 사용하므로 .d.ts에서 .ts로 확…
y5037 54fbb16
refactor(mentor): 다른 API 함수들과의 일관성을 위해 export 처리 변경
y5037 73b534a
chore: img 태그 Image 컴포넌트로 변경
y5037 41ca221
refactor(mentor): getProductData 함수의 리턴 타입 설정
y5037 2af43a5
chore: img 태그 Image 컴포넌트로 변경 후 발생한 타입 에러 수정
y5037 55b5af9
refactor(mentor): T prefix 삭제
y5037 bf67a40
refactor(mentor): props로 받은 상수명은 변수이므로 camelCase로 변경하여 사용
y5037 5117b2b
refactor(mentor): as 제거 후 ref가 null이 아닌 경우에 한정 하도록 수정
y5037 69cbf2e
chore: 코드리뷰대로 getProductData 함수의 파라미터와 리턴 타입을 설정하려 했으나 타입 오류로 인해 임시 원상복구
y5037 d886acd
chore: 오타 수정
y5037 d818031
chore: 상품 등록페이지 img 태그 image 컴포넌트로 변경
y5037 42f67ac
chore: 상품 등록페이지 Image alt 속성값 누락되어 추가
y5037 924cf70
chore: 상품 목록페이지 footer 추가
y5037 1e6ad5f
chore: api 디렉토리 위치 변경 및 상품 리스트 관련 페이지명 변경
y5037 8c8e4bd
chore: Component명 변경 및 hook 디렉토리 추가
y5037 fc88acf
chore: 직관적인 이름을 사용하기 위해 파일명과 컴포넌트명 변경
y5037 ed98b90
feat: 자유게시판 HTML, CSS 레이아웃 구현 완료
y5037 0dfa7db
chore: 반응형 CSS 수정 및 cursor 누락 코드 추가
y5037 ffc1f51
feat: 데이터 출력 완료
y5037 1997765
chore: 레이아웃 CSS 수정
y5037 9c4db88
feat: 타입 지정 완료
y5037 558caf0
feat: 스켈레톤 추가 완료
y5037 dd7e0ea
chore: 컴파일 에러 수정
y5037 d95bea7
chore: 컴파일 오류로 인해 pages의 types 이동
y5037 6bc9e78
feat: prefetch 추가
y5037 0deafd8
chore: 하단 여백 CSS 수정
y5037 3fb3ec7
chore: gitignore에 .next 추가 및 파일 삭제
y5037 968fd87
chore: 상품 디테일 페이지의 상품 썸네일 Error 발생시 대처 코드 추가
y5037 a3990a3
chore: 데이터가 로딩 되는 동안 화면이 비어보이는 문제가 발생하여 조건부 연산자 제거
y5037 9b2c765
chore: 데이터 유무에 따른 UI 출력의 && 연산자를 제거하니 스켈레톤 출력 이슈가 해결되어 setTimeout 제거
y5037 5befb40
feat: Suspense가 작동하지 않아 제거 후 페이지 이동의 로딩 커스팀 훅을 사용하여 적용
y5037 f9a53c3
chore: hook 디렉토리명 hooks로 변경
y5037 9fdae32
chore: useQueryBoard 커스텀 훅 이름 변경
y5037 6ebcc12
chore: 테스트 파일 삭제
y5037 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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,35 +1,73 @@ | ||
| # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
| # Created by https://www.toptal.com/developers/gitignore/api/macos,git,react | ||
| # Edit at https://www.toptal.com/developers/gitignore?templates=macos,git,react | ||
|
|
||
| # dependencies | ||
| /node_modules | ||
| /.pnp | ||
| .pnp.js | ||
| ### Git ### | ||
| # Created by git for backups. To disable backups in Git: | ||
| # $ git config --global mergetool.keepBackup false | ||
| *.orig | ||
|
|
||
| # testing | ||
| /coverage | ||
| # Created by git when using merge tools for conflicts | ||
| *.BACKUP.* | ||
| *.BASE.* | ||
| *.LOCAL.* | ||
| *.REMOTE.* | ||
| *_BACKUP_*.txt | ||
| *_BASE_*.txt | ||
| *_LOCAL_*.txt | ||
| *_REMOTE_*.txt | ||
|
|
||
| # next.js | ||
| /.next/ | ||
| /out/ | ||
| ### macOS ### | ||
| # General | ||
| .DS_Store | ||
| .AppleDouble | ||
| .LSOverride | ||
|
|
||
| # production | ||
| /build | ||
| # Icon must end with two \r | ||
| Icon | ||
|
|
||
| # misc | ||
| .DS_Store | ||
| *.pem | ||
|
|
||
| # debug | ||
| npm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
| # Thumbnails | ||
| ._* | ||
|
|
||
| # Files that might appear in the root of a volume | ||
| .DocumentRevisions-V100 | ||
| .fseventsd | ||
| .Spotlight-V100 | ||
| .TemporaryItems | ||
| .Trashes | ||
| .VolumeIcon.icns | ||
| .com.apple.timemachine.donotpresent | ||
|
|
||
| # Directories potentially created on remote AFP share | ||
| .AppleDB | ||
| .AppleDesktop | ||
| Network Trash Folder | ||
| Temporary Items | ||
| .apdisk | ||
|
|
||
| ### macOS Patch ### | ||
| # iCloud generated files | ||
| *.icloud | ||
|
|
||
| ### react ### | ||
| .DS_* | ||
| *.log | ||
| logs | ||
| **/*.backup.* | ||
| **/*.back.* | ||
|
|
||
| node_modules | ||
| node_modules/ | ||
| node_modules/.cache | ||
| bower_components | ||
|
|
||
| *.sublime* | ||
|
|
||
| # local env files | ||
| .env*.local | ||
| psd | ||
| thumb | ||
| sketch | ||
|
|
||
| # vercel | ||
| .vercel | ||
| ### next ### | ||
| .next | ||
|
|
||
| # typescript | ||
| *.tsbuildinfo | ||
| next-env.d.ts | ||
| # End of https://www.toptal.com/developers/gitignore/api/macos,git,react |
This file contains hidden or 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,40 +1 @@ | ||
| This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). | ||
|
|
||
| ## Getting Started | ||
|
|
||
| First, run the development server: | ||
|
|
||
| ```bash | ||
| npm run dev | ||
| # or | ||
| yarn dev | ||
| # or | ||
| pnpm dev | ||
| # or | ||
| bun dev | ||
| ``` | ||
|
|
||
| Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. | ||
|
|
||
| You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file. | ||
|
|
||
| [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`. | ||
|
|
||
| The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. | ||
|
|
||
| This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. | ||
|
|
||
| ## Learn More | ||
|
|
||
| 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 | ||
|
|
||
| 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. | ||
|
|
||
| Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. | ||
| ## Next.js Project 시작 |
This file contains hidden or 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 |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| import { CommentDataProps, ProductDataProps } from "../api/types"; | ||
| const BASE_URL = "https://panda-market-api.vercel.app"; | ||
|
|
||
| // 베스트/전체 상품 리스트 | ||
| export async function getProductData(params = {}) { | ||
| const query = new URLSearchParams(params).toString(); | ||
| const response = await fetch(`${BASE_URL}/products?${query}`); | ||
|
|
||
| if (!response.ok) { | ||
| throw new Error("상품을 불러오는 데 실패했습니다."); | ||
| } | ||
| const body = await response.json(); | ||
| return body; | ||
| } | ||
|
|
||
| // 디테일 상품 정보 | ||
| export async function getProductId( | ||
| productId: string | string[], | ||
| setProductData: React.Dispatch< | ||
| React.SetStateAction<ProductDataProps | undefined> | ||
| >, | ||
| setLoading: React.Dispatch<React.SetStateAction<boolean>> | ||
| ) { | ||
| const response = await fetch(`${BASE_URL}/products/${productId}`); | ||
|
|
||
| try { | ||
| const body = await response.json(); | ||
| setProductData(body); | ||
| } catch (error) { | ||
| console.log(error); | ||
| } | ||
|
|
||
| if (!response.ok) { | ||
| throw new Error("정보를 불러오는 데 실패했습니다."); | ||
| } | ||
|
|
||
| setLoading(false); | ||
| } | ||
|
|
||
| // 디테일 댓글 | ||
| export async function getComments( | ||
| productId: string | string[], | ||
| setCommentsData: React.Dispatch< | ||
| React.SetStateAction<CommentDataProps | undefined> | ||
| > | ||
| ) { | ||
| const response = await fetch( | ||
| `${BASE_URL}/products/${productId}/comments?limit=10` | ||
| ); | ||
| try { | ||
| const body = await response.json(); | ||
| setCommentsData(body); | ||
| } catch (error) { | ||
| console.log(error); | ||
| } | ||
|
|
||
| if (!response.ok) { | ||
| throw new Error("정보를 불러오는 데 실패했습니다."); | ||
| } | ||
| } |
This file contains hidden or 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 |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| import { StaticImport, StaticRequire } from "next/dist/shared/lib/get-img-props"; | ||
|
|
||
| export interface ProductDataProps { | ||
| createdAt: string; | ||
| description: string; | ||
| favoriteCount: number; | ||
| id: number; | ||
| images:string | StaticImport; | ||
| isFavorite: boolean; | ||
| name: string; | ||
| ownerId: number; | ||
| ownerNickname: string; | ||
| price: number; | ||
| tags: string[]; | ||
| updatedAt: string; | ||
| } | ||
|
|
||
| interface ListWriter { | ||
| id: number; | ||
| image?: string | null; | ||
| nickname: string; | ||
| } | ||
|
|
||
| interface ListComment { | ||
| content: string; | ||
| createdAt: string; | ||
| id: number; | ||
| updatedAt: string; | ||
| writer: ListWriter; | ||
| } | ||
|
|
||
| export interface CommentDataProps { | ||
| list: ListComment[]; | ||
| nextCursor: number; | ||
| } | ||
This file contains hidden or 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 |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import dayjs from "dayjs"; | ||
| import duration, { Duration } from "dayjs/plugin/duration"; | ||
| dayjs.extend(duration); | ||
|
|
||
| export function getTimeDiff(timeToCompare: string) { | ||
| const timeDiffDuration: Duration = dayjs.duration( | ||
| dayjs().diff(timeToCompare) | ||
| ); | ||
| const yearDiff: number = parseInt(timeDiffDuration.format("Y")); | ||
| const monthDiff: number = parseInt(timeDiffDuration.format("M")); | ||
| const dateDiff: number = parseInt(timeDiffDuration.format("D")); | ||
| const hourDiff: number = parseInt(timeDiffDuration.format("H")); | ||
| const minuteDiff: number = parseInt(timeDiffDuration.format("m")); | ||
| const secondDiff: number = parseInt(timeDiffDuration.format("s")); | ||
|
|
||
| if (yearDiff > 0) { | ||
| return `${yearDiff}년 전`; | ||
| } else if (monthDiff > 0) { | ||
| return `${monthDiff}달 전`; | ||
| } else if (dateDiff > 0) { | ||
| return `${dateDiff}일 전`; | ||
| } else if (hourDiff > 0) { | ||
| return `${hourDiff}시간 전`; | ||
| } else if (minuteDiff > 0) { | ||
| return `${minuteDiff}분 전`; | ||
| } else if (secondDiff > 0) { | ||
| return `${secondDiff}초 전`; | ||
| } else { | ||
| return ""; | ||
| } | ||
| } |
This file contains hidden or 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 |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| import styles from "../../styles/app/footer.module.css"; | ||
| import IconInsta from "@/public/assets/images/app/home/ic_instagram.svg"; | ||
| import IconFacebook from "@/public/assets/images/app/home/ic_facebook.svg"; | ||
| import IconYoutube from "@/public/assets/images/app/home/ic_youtube.svg"; | ||
| import IconTwitter from "@/public/assets/images/app/home/ic_twitter.svg"; | ||
| import Link from "next/link"; | ||
|
|
||
| function Footer() { | ||
| return ( | ||
| <footer className={styles.footer}> | ||
| <div className={styles.footerWrap}> | ||
| <p className={styles.copyright}>©codeit - 2024</p> | ||
| <div className={styles.btnLink}> | ||
| <Link href="/privacy">Privacy Policy</Link> | ||
| <Link href="/faq">FAQ</Link> | ||
| </div> | ||
| <ul className={styles.socialBox}> | ||
| <li> | ||
| <Link | ||
| href="https://www.facebook.com/" | ||
| rel="noopener noreferrer" | ||
| target="_blank" | ||
| > | ||
| <IconFacebook /> | ||
| </Link> | ||
| </li> | ||
| <li> | ||
| <Link | ||
| href="https://www.twitter.com/" | ||
| rel="noopener noreferrer" | ||
| target="_blank" | ||
| > | ||
| <IconTwitter /> | ||
| </Link> | ||
| </li> | ||
| <li> | ||
| <Link | ||
| href="https://www.youtube.com/" | ||
| rel="noopener noreferrer" | ||
| target="_blank" | ||
| > | ||
| <IconYoutube /> | ||
| </Link> | ||
| </li> | ||
| <li> | ||
| <Link | ||
| href="https://www.instagram.com/" | ||
| rel="noopener noreferrer" | ||
| target="_blank" | ||
| > | ||
| <IconInsta /> | ||
| </Link> | ||
| </li> | ||
| </ul> | ||
| </div> | ||
| </footer> | ||
| ); | ||
| } | ||
|
|
||
| export default Footer; |
This file contains hidden or 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 |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| import { useRouter } from "next/router"; | ||
| import Link from "next/link"; | ||
| import Image from "next/image"; | ||
| import styles from "../../styles/app/navi.module.css"; | ||
| import NavLogoImg from "@/public/assets/images/app/navi/logo.svg"; | ||
| import profileDefaultImg from "@/public/assets/images/app/navi/profile_default.png"; | ||
|
|
||
| const menuData = [ | ||
| { id: 1, name: "자유게시판", path: "/boards" }, | ||
| { id: 2, name: "중고마켓", path: "/items" }, | ||
| ]; | ||
|
|
||
| function ItemListNav() { | ||
| const router = useRouter(); | ||
|
|
||
| return ( | ||
| <div className={styles.fixContainer}> | ||
| <nav className={styles.navCover}> | ||
| <div className={styles.pageControl}> | ||
| <Link href="/" prefetch={true}> | ||
| <div className={styles.btnLogo}> | ||
| <NavLogoImg /> | ||
| <p className={styles.companyName}>판다마켓</p> | ||
| </div> | ||
| </Link> | ||
| <div className={styles.btnWrap}> | ||
| {menuData.map((menu) => { | ||
| return ( | ||
| <Link | ||
| key={menu.id} | ||
| href={menu.path} | ||
| prefetch={true} | ||
| className={`${styles.btnNavMenu} ${ | ||
| menu.path === router.pathname ? styles.isActive : "" | ||
| }`} | ||
| > | ||
| {menu.name} | ||
| </Link> | ||
| ); | ||
| })} | ||
| </div> | ||
| </div> | ||
| {/* 사용자 정보를 담은 프로필 또는 아바타이므로 이 기능만 제공해주는 콤포넌트를 분리하는 것도 추후 고려 */} | ||
| <div className={styles.userControl}> | ||
| <div className={styles.circle}> | ||
| <Image src={profileDefaultImg} alt="기본프로필이미지" /> | ||
| </div> | ||
| </div> | ||
| </nav> | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| export default ItemListNav; |
This file contains hidden or 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 |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import styles from "../../styles/app/loading.module.css"; | ||
|
|
||
| export const Loading = () => { | ||
| return ( | ||
| <div className={styles.loaderContainer}> | ||
| <span className={styles.loader}></span> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default Loading; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
items에 정의된 타입이랑 다른 건가요?(링크) 다르게 유지해야 할 필요가 있는게 아니라 동일한 api 데이터 받는 거라면 하나를 보도록 하는게 좋을 것 같아요.