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

[김희진] sprint9 #117

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
7 changes: 5 additions & 2 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}
images: {
domains: ['sprint-fe-project.s3.ap-northeast-2.amazonaws.com'],
},
};

module.exports = nextConfig
module.exports = nextConfig;
12 changes: 9 additions & 3 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import '@/styles/globals.css'
import type { AppProps } from 'next/app'
import GlobalLayout from '@/src/components/GlobalLayout';
import '@/styles/reset.css';
import '@/styles/globals.css';
import type { AppProps } from 'next/app';

export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
return (
<GlobalLayout>
<Component {...pageProps} />
</GlobalLayout>
);
}
6 changes: 3 additions & 3 deletions pages/_document.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Html, Head, Main, NextScript } from 'next/document'
import { Html, Head, Main, NextScript } from 'next/document';

export default function Document() {
return (
<Html lang="en">
<Html lang="kr">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
);
}
13 changes: 0 additions & 13 deletions pages/api/hello.ts

This file was deleted.

80 changes: 80 additions & 0 deletions pages/boards/components/BestBoardCard.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
.bestBoardCardContainer {
border-radius: 8px;
background: var(--Secondary-50, #f9fafb);
padding: 0px 24px;
padding-bottom: 15px;

display: flex;
flex-direction: column;
gap: 18px;
}

.bestBoardBadge {
width: 102px;
height: 30px;
text-align: center;
padding: 2px 24px;
background: var(--Primary-100, #3692ff);
border-radius: 0px 0px 16px 16px;

display: flex;
align-items: center;
gap: 4px;
}

.bestText {
color: #fff;
font-size: 16px;
font-weight: 600;
}

.contentContainer {
width: 100%;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}

.contentTitle {
color: var(--Secondary-800, #1f2937);
font-size: 20px;
font-weight: 600;
max-width: 256px;
}

.contentImgWrapper {
position: relative;
width: 72px;
height: 72px;

border-radius: 6px;
border: 1px solid var(--Secondary-200, #e5e7eb);
background: #fff;
}

.additionalInfo {
color: var(--Secondary-600, #4b5563);
font-size: 14px;
font-weight: 400;

display: flex;
justify-content: space-between;
align-items: center;
gap: 8px;
}

.likeCountWrapper {
flex: 1;

display: flex;
align-items: center;
gap: 4px;
}

/* tablet */
@media screen and (max-width: 1199px) {
.contentTitle {
gap: 40px;
max-width: 180px;
}
}
42 changes: 42 additions & 0 deletions pages/boards/components/BestBoardCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Image from 'next/image';
import styles from './BestBoardCard.module.css';
import medalSvg from '@/src/assets/ic_medal.svg';
import heardSvg from '@/src/assets/ic_heart.svg';
import { Board } from '@/src/apis/boardTypes';

interface BestBoardCardProps
extends Pick<
Board,
'title' | 'image' | 'writer' | 'likeCount' | 'createdAt'
> {}
Comment on lines +7 to +11
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2:
추가로 정의할 타입이 있지 않다면 아래처럼 하시는 것을 추천드립니다.

Suggested change
interface BestBoardCardProps
extends Pick<
Board,
'title' | 'image' | 'writer' | 'likeCount' | 'createdAt'
> {}
type BestBoardCardProps = Pick<
Board,
'title' | 'image' | 'writer' | 'likeCount' | 'createdAt'
>;


export default function BestBoardCard({
title,
image,
writer,
likeCount,
createdAt,
}: BestBoardCardProps) {
return (
<div className={styles.bestBoardCardContainer}>
<div className={styles.bestBoardBadge}>
<Image src={medalSvg} alt="medal" width={16} height={16} />
<span className={styles.bestText}>Best</span>
</div>
<div className={styles.contentContainer}>
<h4 className={styles.contentTitle}>{title}</h4>
<div className={styles.contentImgWrapper}>
<Image src={image} alt="medal" fill style={{ objectFit: 'cover' }} />
</div>
</div>
<div className={styles.additionalInfo}>
<span>{writer.nickname}</span>
<div className={styles.likeCountWrapper}>
<Image src={heardSvg} alt="heardIcon" width={16} height={16} />
<span>{likeCount}</span>
</div>
<span>{new Date(createdAt).toLocaleDateString()}</span>
</div>
</div>
);
}
43 changes: 43 additions & 0 deletions pages/boards/components/BestBoards.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
.bestBoards {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24px;

margin-bottom: 40px;
}

.title {
color: var(--Secondary-900, #111827);
font-size: 20px;
font-weight: 700;

padding: 24px 0;
}

/* tablet */
@media screen and (max-width: 1199px) {
.bestBoards {
grid-template-columns: repeat(2, 1fr);
gap: 16px;
margin-bottom: 24px;
}

.bestBoards > *:nth-child(n + 3) {
display: none;
}
}

/* mobile */
@media screen and (max-width: 767px) {
.bestBoards {
grid-template-columns: repeat(1, 1fr);
}

.title {
padding: 16px 0;
}

.bestBoards > *:nth-child(n + 2) {
display: none;
}
}
20 changes: 20 additions & 0 deletions pages/boards/components/BestBoards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Board } from '@/src/apis/boardTypes';
import BestBoardCard from './BestBoardCard';
import styles from './BestBoards.module.css';

interface BestBoardsProps {
boards: Board[];
}

export default function BestBoards({ boards }: BestBoardsProps) {
return (
<section>
<h3 className={styles.title}>베스트 게시글</h3>
<div className={styles.bestBoards}>
{boards.map((board) => (
<BestBoardCard key={board.id} {...board} />
))}
</div>
</section>
);
}
46 changes: 46 additions & 0 deletions pages/boards/components/Boards.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.boardsHeader {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24px;
}

.title {
color: var(--Secondary-800, #1f2937);
font-size: 20px;
font-weight: 700;
}

.searchBar {
padding: 9px 20px 9px 16px;
border-radius: 12px;
background: var(--Secondary-100, #f3f4f6);

display: flex;
align-items: center;
gap: 4px;
}

.searchData {
font-size: 16px;
font-weight: 400;
background: transparent;
}

.searchData::placeholder {
color: var(--Secondary-400, #9ca3af);
}

/* tablet */
@media screen and (max-width: 1199px) {
.boardsHeader {
margin-bottom: 48px;
}
}

/* mobile */
@media screen and (max-width: 767px) {
.boardsHeader {
margin-bottom: 16px;
}
}
26 changes: 26 additions & 0 deletions pages/boards/components/Boards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Image from 'next/image';
import Button from '@/src/components/Button';
import styles from './Boards.module.css';
import searchSvg from '@/src/assets/ic_search.svg';

export default function Boards() {
return (
<div>
<div className={styles.boardsHeader}>
<h3 className={styles.title}>게시글</h3>
<div>
<Button>글쓰기</Button>
</div>
</div>
<div className={styles.filter}>
<div className={styles.searchBar}>
<Image src={searchSvg} alt="searchIcon" width={24} height={24} />
<input
className={styles.searchData}
placeholder="검색할 상품을 입력해주세요"
/>
</div>
</div>
</div>
);
}
33 changes: 33 additions & 0 deletions pages/boards/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { GetStaticProps } from 'next';
import BestBoards from './components/BestBoards';
import { Board } from '@/src/apis/boardTypes';
import { getBoards } from '@/src/apis/boardsApi';
import Boards from './components/Boards';

interface BoardsIndexProps {
boards: Board[];
}

export default function BoardsIndex({ boards }: BoardsIndexProps) {
return (
<div>
<BestBoards boards={boards} />
<Boards />
</div>
);
}

export const getStaticProps: GetStaticProps = async () => {
const { list } = await getBoards({
page: 1,
pageSize: 3,
orderBy: 'like',
});

return {
props: {
boards: list || [],
},
revalidate: 600, // Re-generate the page every 600 seconds (ISR)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3:
적절하게 잘 사용하셨네요! 관련해서 읽어보면 좋을 글이 있어서 첨부합니다~

https://velog.io/@dldngus5/nextjs-revalidate

};
};
Loading
Loading