-
Notifications
You must be signed in to change notification settings - Fork 35
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
[최영선] sprint10 #311
The head ref may contain hidden characters: "Next-\uCD5C\uC601\uC120-sprint10"
[최영선] sprint10 #311
Changes from all commits
5841bb1
b8f4163
d5296c1
ef5780d
168a383
0d1916f
a1720cb
d3d0894
3c64162
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,135 @@ | ||
import FormatRelativeTime from "@/utils/FormatRelativeTime"; | ||
import { useEffect, useState } from "react"; | ||
import styled from "styled-components"; | ||
import axios from "@/lib/axios"; | ||
import Image from "next/image"; | ||
|
||
const StyledSection = styled.section` | ||
margin-top: 100px; | ||
border-bottom: 1px solid var(--gray-200); | ||
background-color: var(--gray-20); | ||
`; | ||
const StyledList = styled.ul` | ||
padding: 0; | ||
`; | ||
const StyledListItem = styled.li` | ||
list-style-type: none; | ||
`; | ||
const StyledContent = styled.p` | ||
font-size: 16px; | ||
font-weight: 400; | ||
margin-bottom: 24px; | ||
`; | ||
const StyledBottomSection = styled.section` | ||
display: flex; | ||
align-items: center; | ||
gap: 12px; | ||
`; | ||
const StyledWriterImg = styled.img` | ||
width: 50px; | ||
height: 50px; | ||
border-radius: 50%; | ||
`; | ||
const StyledInfo = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
gap: 4px; | ||
`; | ||
const StyledNickname = styled.p` | ||
font-size: 14px; | ||
font-weight: 400; | ||
margin: 0; | ||
`; | ||
const StyledTime = styled.div` | ||
font-size: 12px; | ||
font-weight: 400; | ||
color: var(--gray-400); | ||
margin: 0; | ||
`; | ||
|
||
const StyledEmptyComment = styled.p` | ||
font-size: 16px; | ||
font-weight: 400; | ||
text-align: center; | ||
color: var(--gray-400); | ||
`; | ||
|
||
interface Comment { | ||
writer: { | ||
image: string; | ||
nickname: string; | ||
id: number; | ||
}; | ||
updatedAt: string; | ||
createdAt: string; | ||
content: string; | ||
id: number; | ||
} | ||
|
||
function ArticleCommentList({ id }: any) { | ||
const [comments, setComments] = useState<Comment[]>([]); | ||
|
||
async function getArticleComments() { | ||
const query = { | ||
limit: 10, | ||
}; | ||
const res = await axios.get( | ||
`/articles/${id}/comments?limit=${query.limit}` | ||
); | ||
const nextComments = res.data.list; | ||
setComments(nextComments); | ||
} | ||
|
||
useEffect(() => { | ||
getArticleComments(); | ||
}, [id]); | ||
|
||
if (comments.length === 0) { | ||
return ( | ||
<div className="empty-comment" style={{ textAlign: "center" }}> | ||
<Image | ||
unoptimized={true} | ||
width={140} | ||
height={140} | ||
src="/image/img_comment_empty.png" | ||
alt="No comments" | ||
/> | ||
<StyledEmptyComment> | ||
아직 댓글이 없어요, | ||
<br /> 지금 댓글을 달아보세요! | ||
</StyledEmptyComment> | ||
</div> | ||
); | ||
} | ||
return ( | ||
<div> | ||
<StyledSection> | ||
<StyledList> | ||
{comments.map((comment) => ( | ||
<StyledListItem key={comment.id}> | ||
<StyledContent>{comment.content}</StyledContent> | ||
<StyledBottomSection> | ||
<StyledWriterImg | ||
src={ | ||
comment.writer.image | ||
? comment.writer.image | ||
: "/image/profile_img_none.png" | ||
} | ||
alt="프로필 이미지" | ||
/> | ||
Comment on lines
+112
to
+119
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. 웹 접근성 관점에서 alt 속성 값에 이런 경우 사용자닉네임도 넣어서 값을 만들면 대체 텍스트를 보다 더 구체적으로 만들 수 있어요.
Comment on lines
+108
to
+119
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. 보통 이렇게 map을 사용할 수 있는 부분은 별도의 컴포넌트로 분리하는걸 추천드려요. UI가 분리되고, 가독성이 좋아지거든요.
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. 최종적으로 아래처럼 바꿀 수 있어요.
|
||
<StyledInfo> | ||
<StyledNickname>{comment.writer.nickname}</StyledNickname> | ||
<StyledTime> | ||
<FormatRelativeTime time={comment.updatedAt} /> | ||
</StyledTime> | ||
</StyledInfo> | ||
</StyledBottomSection> | ||
</StyledListItem> | ||
))} | ||
</StyledList> | ||
</StyledSection> | ||
</div> | ||
); | ||
} | ||
|
||
export default ArticleCommentList; |
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.
이 부분은 아래처럼
useArticleComments
커스텀 훅 같은걸 만들어서 재사용 가능한 훅을 만들어 볼 수 있겠어요. 😸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.
그 이후에는 아래처럼 사용해보면 되겠죠?