-
Notifications
You must be signed in to change notification settings - Fork 18
[김수영] sprint9 #118
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
The head ref may contain hidden characters: "Next-\uAE40\uC218\uC601-sprint9"
[김수영] sprint9 #118
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"presets": ["next/babel"], | ||
"plugins": ["babel-plugin-styled-components"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
parse_git_branch() { | ||
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/' | ||
} | ||
export PS1="\u@\h \W\[\033[32m\]\$(parse_git_branch)\[\033[00m\] $ " |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import styled from "styled-components"; | ||
|
||
export const BoardPage = styled.div` | ||
width:100%; | ||
display:flex; | ||
flex-direction:column; | ||
align-items:center; | ||
justify-content:center; | ||
`; | ||
export const BoardPageContainer = styled.div` | ||
max-width:1200px; | ||
width:100%; | ||
margin-top:24px; | ||
display:flex; | ||
gap:40px; | ||
flex-direction:column; | ||
|
||
@media(max-width:1199px){ | ||
max-width:696px; | ||
} | ||
@media(max-width:767px){ | ||
max-width:343px; | ||
} | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import styled from "styled-components"; | ||
|
||
export const MainWrapper = styled.div` | ||
width: 100%; | ||
height: 100%; | ||
display: flex; | ||
align-items: center; | ||
`; | ||
export const MainContainer = styled.div` | ||
width: 100%; | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import React, { useState, useEffect, useCallback} from 'react'; | ||
import * as BS from './Styled'; | ||
import BestPostCard from './BestPostCard'; | ||
import { Item, ItemList } from './PostList'; | ||
import { getArticles } from '@/pages/api/api'; | ||
|
||
interface ItemCardProps { | ||
item: Item; | ||
} | ||
|
||
interface ItemListProps { | ||
itemList : ItemList; | ||
} | ||
|
||
export default function BestPost() { | ||
const [itemList, setItemList] = useState<ItemList>({ totalCount: 0, list: [] }); | ||
const [pageSize, setPageSize] = useState(4); | ||
const [order, setOrder] = useState('like'); | ||
const fetchSortedData = useCallback(async () => { | ||
try { | ||
const articles = await getArticles({ orderBy: order, pageSize }); | ||
setItemList(articles); | ||
console.log(articles); | ||
} catch (error) { | ||
console.error('Error fetching articles:', error); | ||
} | ||
}, [order, pageSize]); | ||
|
||
useEffect(() => { | ||
fetchSortedData(); | ||
}, [fetchSortedData]); | ||
|
||
useEffect(() => { | ||
const handleResize = () => { | ||
const width = window.innerWidth; | ||
if (width < 767) { | ||
setPageSize(1); | ||
} else if (width < 1280) { | ||
setPageSize(2); | ||
} else { | ||
setPageSize(4); | ||
} | ||
}; | ||
|
||
window.addEventListener('resize', handleResize); | ||
handleResize(); | ||
|
||
return () => { | ||
window.removeEventListener('resize', handleResize); | ||
}; | ||
}, []); | ||
|
||
return ( | ||
<BS.BestPostConainer> | ||
<BS.Title>베스트 게시글</BS.Title> | ||
<BS.BestCardListContainer> | ||
{itemList.list.map((item) => ( | ||
<BestPostCard key={item.id} item={item} /> | ||
))} | ||
</BS.BestCardListContainer> | ||
</BS.BestPostConainer> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import React from 'react'; | ||
import * as BS from './Styled'; | ||
import MedalIcon from '../common/images/ic_medal.png'; | ||
import LikeIcon from '../common/images/ic_heart.png'; | ||
import DefaultImg from '../common/images/default.png'; | ||
import { Item } from './PostList'; | ||
import formatDate from '../common/function/formatDate'; | ||
|
||
interface ItemCardProps { | ||
item:Item; | ||
} | ||
|
||
|
||
const BestPostCard:React.FC<ItemCardProps> = ({ item }) => { | ||
return ( | ||
<BS.BestCardContainer> | ||
<BS.BestBadgeContainer> | ||
<BS.MedalIcon src={MedalIcon} alt="메달아이콘" /> | ||
<BS.BestText>Best</BS.BestText> | ||
</BS.BestBadgeContainer> | ||
<BS.BestPostContentContainer> | ||
<BS.BestPostContentText>{item.title}</BS.BestPostContentText> | ||
<BS.BestPostImg | ||
src={item.image ? item.image : DefaultImg} | ||
width={72} | ||
height={72} | ||
alt="게시물 이미지" > | ||
</BS.BestPostImg> | ||
</BS.BestPostContentContainer> | ||
<BS.SubContainer> | ||
<BS.InfoContainer> | ||
<BS.Writer>{item.writer.nickname}</BS.Writer> | ||
<BS.LikeIcon src={LikeIcon} alt="좋아요 아이콘"></BS.LikeIcon> | ||
<BS.LikeCount>{item.likeCount}</BS.LikeCount> | ||
</BS.InfoContainer> | ||
<BS.PostDate>{formatDate(item.createdAt)}</BS.PostDate> | ||
</BS.SubContainer> | ||
</BS.BestCardContainer> | ||
); | ||
} | ||
export default BestPostCard; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import React from 'react'; | ||
import * as PS from './Styled'; | ||
import DefaultImg from '../common/images/default.png'; | ||
import LikeIcon from '../common/images/ic_heart.png'; | ||
import ProfileImg from '../common/images/profile.png'; | ||
import { Item } from './PostList'; | ||
import formatDate from '../common/function/formatDate'; | ||
|
||
interface ItemCardProps { | ||
item: Item; | ||
} | ||
|
||
const PostCard: React.FC<ItemCardProps> = ({ item }) => { | ||
return ( | ||
<PS.PostCardContainer> | ||
<PS.PostContentContainer> | ||
<PS.BestPostContentText>{item.title}</PS.BestPostContentText> | ||
<PS.BestPostImg | ||
src={item.image ? item.image : DefaultImg} | ||
width={72} | ||
height={72} | ||
alt="게시물 이미지" | ||
/> | ||
</PS.PostContentContainer> | ||
<PS.SubContainer> | ||
<PS.InfoContainer> | ||
<PS.ProfileImg | ||
src={ProfileImg} | ||
|
||
alt="프로필 이미지" | ||
/> | ||
<PS.Writer>{item.writer.nickname}</PS.Writer> | ||
<PS.PostDate>{formatDate(item.createdAt)}</PS.PostDate> | ||
</PS.InfoContainer> | ||
<PS.InfoContainer> | ||
<PS.LikeIcon | ||
src={LikeIcon} | ||
alt="좋아요 아이콘" | ||
/> | ||
<PS.LikeCount>{item.likeCount}</PS.LikeCount> | ||
</PS.InfoContainer> | ||
</PS.SubContainer> | ||
</PS.PostCardContainer> | ||
); | ||
} | ||
|
||
export default PostCard; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import React, { useState, useEffect, useCallback } from 'react'; | ||
import { useRouter } from 'next/router'; | ||
import * as BS from './Styled'; | ||
import PostCard from './PostCard'; | ||
import { getArticles } from '@/pages/api/api'; | ||
|
||
export interface Item { | ||
id: number; | ||
title: string; | ||
content: string; | ||
image: string; | ||
writer: Writer; | ||
likeCount: number; | ||
updatedAt: string; | ||
createdAt: string; | ||
} | ||
|
||
interface Writer { | ||
nickname: string; | ||
id: number; | ||
} | ||
|
||
export interface ItemList { | ||
totalCount: number; | ||
list: Item[]; | ||
} | ||
|
||
export default function PostList() { | ||
const [itemList, setItemList] = useState<ItemList>({ totalCount: 0, list: [] }); | ||
const [pageSize, setPageSize] = useState(4); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: enum PAGE_SIZE_BY_SCREEN {
PC = 4,
TABLET = 2,
MOBILE = 1,
}
const getPageSize = (width: number): PAGE_SIZE_BY_SCREEN => {
if (width < 768) return PAGE_SIZE_BY_SCREEN.MOBILE;
if (width < 1200) return PAGE_SIZE_BY_SCREEN.TABLET;
return PAGE_SIZE_BY_SCREEN.PC;
};
const [pageSize, setPageSize] = useState<PAGE_SIZE_BY_SCREEN>(); 위의 예시처럼 enum으로 어떤 경우 4이 되는지를 명시해주셔도 좋습니다. |
||
const [order, setOrder] = useState('recent'); | ||
swim-kim marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const [isDropdownOpen, setIsDropdownOpen] = useState(false); | ||
const [search, setSearch] = useState(''); | ||
|
||
const router = useRouter(); | ||
const{ q } = router.query; | ||
|
||
const toggleDropdown = () => { | ||
setIsDropdownOpen(!isDropdownOpen); | ||
}; | ||
|
||
const handleNewestClick = () => { | ||
setOrder('recent'); | ||
setIsDropdownOpen(false); | ||
}; | ||
|
||
const handleLikeClick = () => { | ||
setOrder('like'); | ||
setIsDropdownOpen(false); | ||
}; | ||
|
||
const handleChange = (e:React.ChangeEvent<HTMLInputElement>) => setSearch(e.target.value); | ||
const fetchSortedData = useCallback(async () => { | ||
try { | ||
const articles = await getArticles({ orderBy: order, pageSize: 1, keyword:search}); | ||
const totalCount = articles.totalCount; | ||
Comment on lines
+55
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: |
||
const allArticles = await getArticles({ orderBy: order, pageSize: totalCount, keyword:search}); | ||
setItemList(allArticles); | ||
console.log(allArticles); | ||
swim-kim marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} catch (error) { | ||
console.error('Error fetching articles:', error); | ||
} | ||
}, [order, search]); | ||
|
||
useEffect(() => { | ||
fetchSortedData(); | ||
}, [fetchSortedData]); | ||
|
||
return ( | ||
<BS.PostListContainer> | ||
<BS.PostListHeader> | ||
<BS.Title>게시물</BS.Title> | ||
<BS.PostButton>글쓰기</BS.PostButton> | ||
</BS.PostListHeader> | ||
<BS.SearchContainer> | ||
<BS.SearchBox | ||
type='text' | ||
placeholder='검색할 상품을 입력해주세요' | ||
onChange={handleChange} | ||
value={search} | ||
> | ||
</BS.SearchBox> | ||
<BS.DropdownButtonContainer> | ||
<BS.DropdownButton onClick={toggleDropdown}> | ||
{order === 'recent' ? '최신순' : '좋아요순'} <BS.DropdownArrow>▾</BS.DropdownArrow> | ||
</BS.DropdownButton> | ||
<BS.DropdownMenu $isOpen={isDropdownOpen}> | ||
<BS.DropdownOption onClick={handleNewestClick}>최신순</BS.DropdownOption> | ||
<BS.DropdownOption onClick={handleLikeClick}>좋아요순</BS.DropdownOption> | ||
</BS.DropdownMenu> | ||
</BS.DropdownButtonContainer> | ||
Comment on lines
+83
to
+91
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: |
||
</BS.SearchContainer> | ||
{itemList.list.map((item) => ( | ||
<PostCard key={item.id} item={item} /> | ||
))} | ||
</BS.PostListContainer> | ||
); | ||
} |
Uh oh!
There was an error while loading. Please reload this page.