-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* test: 댓글 조회 및 등록 msw 적용 * feat: Comment 컴포넌트 구현 * feat: CommentList 컴포넌트 구현 * feat: SongPage에 killingPart 별로 CommentList 적용 * config: ol, ul에 list-style 제거 * fix: 익명 프로필 asset 수정 * design: 킬링파트 투표 많은순으로 워딩 변경 * feat: SongPage(듣기)와 SongDetailPage(투표) 페이지 전환 추가 * fix: 킬링파트 순위 변경시 댓글이 변경되지 않던 버그 수정
- Loading branch information
1 parent
570a6af
commit 143c839
Showing
14 changed files
with
359 additions
and
33 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains 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,81 @@ | ||
import { styled } from 'styled-components'; | ||
import shookshook from '@/assets/icon/shookshook.svg'; | ||
import { Spacing } from '../@common'; | ||
|
||
interface CommentProps { | ||
content: string; | ||
createdAt: string; | ||
} | ||
|
||
// FIXME: 분리 및 포맷 정리, ~일 전 말고도 세분화 필요 | ||
const rtf = new Intl.RelativeTimeFormat('ko', { | ||
numeric: 'always', | ||
}); | ||
|
||
const Comment = ({ content, createdAt }: CommentProps) => { | ||
const time = Math.ceil( | ||
(new Date(createdAt).getTime() - new Date().getTime()) / (1000 * 60 * 60 * 24) | ||
); | ||
|
||
return ( | ||
<Wrapper> | ||
<Flex> | ||
<Profile> | ||
<img src={shookshook} alt="익명 프로필" /> | ||
</Profile> | ||
<Spacing direction="horizontal" size={14} /> | ||
<Box tabIndex={0} role="comment"> | ||
<Username>익명</Username> | ||
<RelativeTime>{rtf.format(time, 'day')}</RelativeTime> | ||
<Content>{content}</Content> | ||
</Box> | ||
</Flex> | ||
</Wrapper> | ||
); | ||
}; | ||
|
||
export default Comment; | ||
|
||
const Wrapper = styled.li` | ||
width: 100%; | ||
margin-bottom: 16px; | ||
`; | ||
|
||
const Flex = styled.div` | ||
display: flex; | ||
width: 100%; | ||
align-items: flex-start; | ||
`; | ||
|
||
const Profile = styled.div` | ||
width: 40px; | ||
height: 40px; | ||
|
||
border-radius: 100%; | ||
background-color: white; | ||
|
||
overflow: hidden; | ||
`; | ||
|
||
const Box = styled.div` | ||
flex: 1; | ||
`; | ||
|
||
const Username = styled.span` | ||
font-size: 14px; | ||
`; | ||
|
||
const RelativeTime = styled.span` | ||
margin-left: 5px; | ||
font-size: 12px; | ||
color: #aaaaaa; | ||
`; | ||
|
||
const Content = styled.div` | ||
font-size: 14px; | ||
|
||
display: -webkit-box; | ||
-webkit-box-orient: vertical; | ||
-webkit-line-clamp: 3; | ||
overflow: hidden; | ||
`; |
This file contains 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,168 @@ | ||
import { useEffect, useState } from 'react'; | ||
import { css, styled } from 'styled-components'; | ||
import fetcher from '@/apis'; | ||
import shookshook from '@/assets/icon/shookshook.svg'; | ||
import useFetch from '@/hooks/@common/useFetch'; | ||
import { useMutation } from '@/hooks/@common/useMutation'; | ||
import { Spacing } from '../@common'; | ||
import useToastContext from '../@common/Toast/hooks/useToastContext'; | ||
import Comment from './Comment'; | ||
|
||
interface Comment { | ||
id: number; | ||
content: string; | ||
createdAt: string; | ||
} | ||
|
||
interface CommentListProps { | ||
songId: string; | ||
partId: number; | ||
} | ||
|
||
const CommentList = ({ songId, partId }: CommentListProps) => { | ||
const [newComment, setNewComment] = useState(''); | ||
|
||
const { data: comments, fetchData: getComment } = useFetch<Comment[]>(() => | ||
fetcher(`/songs/${songId}/parts/${partId}/comments`, 'GET') | ||
); | ||
|
||
const { mutateData } = useMutation(() => | ||
fetcher(`/songs/${songId}/parts/${partId}/comments`, 'POST', { content: newComment }) | ||
); | ||
const { showToast } = useToastContext(); | ||
|
||
const resetNewComment = () => setNewComment(''); | ||
|
||
const changeNewComment: React.ChangeEventHandler<HTMLInputElement> = ({ | ||
currentTarget: { value }, | ||
}) => setNewComment(value); | ||
|
||
const submitNewComment: React.FormEventHandler<HTMLFormElement> = async (event) => { | ||
event.preventDefault(); | ||
|
||
await mutateData(); | ||
|
||
showToast('댓글이 등록되었습니다.'); | ||
resetNewComment(); | ||
getComment(); | ||
}; | ||
|
||
useEffect(() => { | ||
getComment(); | ||
}, [partId]); | ||
|
||
if (!comments) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<div> | ||
<Spacing direction="vertical" size={24} /> | ||
<h3>댓글 {comments.length}개</h3> | ||
<Spacing direction="vertical" size={24} /> | ||
<form onSubmit={submitNewComment}> | ||
<Flex> | ||
<Profile> | ||
<img src={shookshook} alt="익명 프로필" /> | ||
</Profile> | ||
<Input | ||
type="text" | ||
value={newComment} | ||
onChange={changeNewComment} | ||
placeholder="댓글 추가..." | ||
maxLength={200} | ||
/> | ||
</Flex> | ||
<FlexEnd> | ||
<Cancel type="button" onClick={resetNewComment} aria-label="댓글 작성 취소"> | ||
취소 | ||
</Cancel> | ||
<Submit aria-label="댓글 작성 완료" disabled={newComment === ''}> | ||
댓글 | ||
</Submit> | ||
</FlexEnd> | ||
</form> | ||
<Spacing direction="vertical" size={20} /> | ||
<Comments> | ||
{comments.map(({ id, content, createdAt }) => ( | ||
<Comment key={id} content={content} createdAt={createdAt} /> | ||
))} | ||
</Comments> | ||
</div> | ||
); | ||
}; | ||
|
||
export default CommentList; | ||
|
||
const Flex = styled.div` | ||
display: flex; | ||
align-items: flex-start; | ||
gap: 14px; | ||
`; | ||
|
||
const Profile = styled.div` | ||
width: 40px; | ||
height: 40px; | ||
border-radius: 100%; | ||
background-color: white; | ||
overflow: hidden; | ||
`; | ||
|
||
const Input = styled.input` | ||
flex: 1; | ||
margin: 0 8px; | ||
border: none; | ||
-webkit-box-shadow: none; | ||
box-shadow: none; | ||
margin: 0; | ||
padding: 0; | ||
background-color: transparent; | ||
border-bottom: 1px solid white; | ||
outline: none; | ||
font-size: 14px; | ||
`; | ||
|
||
const FlexEnd = styled.div` | ||
display: flex; | ||
justify-content: flex-end; | ||
gap: 10px; | ||
`; | ||
|
||
const buttonBase = css` | ||
width: 50px; | ||
height: 36px; | ||
font-size: 14px; | ||
border-radius: 10px; | ||
`; | ||
|
||
const Cancel = styled.button` | ||
${buttonBase} | ||
&:hover, | ||
&:focus { | ||
background-color: ${({ theme }) => theme.color.secondary}; | ||
} | ||
`; | ||
|
||
const Submit = styled.button` | ||
${buttonBase} | ||
background-color: ${({ theme }) => theme.color.primary}; | ||
&:hover, | ||
&:focus { | ||
background-color: #de5484; | ||
} | ||
&:disabled { | ||
background-color: ${({ theme }) => theme.color.secondary}; | ||
} | ||
`; | ||
|
||
const Comments = styled.ol` | ||
gap: 10px; | ||
`; |
This file contains 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 @@ | ||
export { default } from './CommentList'; |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Oops, something went wrong.