From 05a2d2d6fd70250673b8d0cd32f168c07b4d3097 Mon Sep 17 00:00:00 2001 From: HAEUN KIM Date: Sun, 11 Apr 2021 00:26:14 +0900 Subject: [PATCH 1/7] =?UTF-8?q?[#63]=20=EB=8C=93=EA=B8=80=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=BB=8D=EB=8D=B0=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Comment/AuthorComment.tsx | 76 ++++++++++++++++++++++ components/Comment/CommentArea.tsx | 59 +++++++++++++++++ components/Comment/CommentBody.tsx | 85 +++++++++++++++++++++++++ components/Comment/CommentBottom.tsx | 43 +++++++++++++ components/Comment/CommentItem.tsx | 39 ++++++++++++ components/Comment/CommentNav.tsx | 55 ++++++++++++++++ components/Comment/CommentThumbnail.tsx | 34 ++++++++++ components/Comment/Created.tsx | 56 ++++++++++++++++ components/Comment/ReplyComponent.tsx | 67 +++++++++++++++++++ components/Comment/comment.stories.tsx | 51 +++++++++++++++ components/Comment/index.tsx | 39 ++++++++++++ components/Icon/svg/index.ts | 1 + components/Icon/svg/plus.svg | 1 + types/index.ts | 13 +++- 14 files changed, 618 insertions(+), 1 deletion(-) create mode 100644 components/Comment/AuthorComment.tsx create mode 100644 components/Comment/CommentArea.tsx create mode 100644 components/Comment/CommentBody.tsx create mode 100644 components/Comment/CommentBottom.tsx create mode 100644 components/Comment/CommentItem.tsx create mode 100644 components/Comment/CommentNav.tsx create mode 100644 components/Comment/CommentThumbnail.tsx create mode 100644 components/Comment/Created.tsx create mode 100644 components/Comment/ReplyComponent.tsx create mode 100644 components/Comment/comment.stories.tsx create mode 100644 components/Comment/index.tsx create mode 100644 components/Icon/svg/plus.svg diff --git a/components/Comment/AuthorComment.tsx b/components/Comment/AuthorComment.tsx new file mode 100644 index 0000000..b3232c6 --- /dev/null +++ b/components/Comment/AuthorComment.tsx @@ -0,0 +1,76 @@ +import React from 'react'; +import { FeedAuthor } from 'types/index'; +import styled from '@emotion/styled'; +import Created from 'components/Comment/Created'; + +export type AuthorCommentProps = { + content: string; + author: FeedAuthor; + created: string; +}; + +function AuthorComment({ content, author, created }: AuthorCommentProps) { + // Todo : form 요소 크기 + return ( + + + + + + + +
+ + {author.displayId} + + {content} +
+ +
+
+ ); +} + +const StyledAtag = styled.a` + text-decoration: none; + color: inherit; +`; + +const StyledImg = styled.img` + height: 42px; + width: 42px; +`; + +const StyledCommentThumbnail = styled.div` + display: inline-block; + border-radius: 70%; + overflow: hidden; + object-fit: cover; + height: 42px; + width: 42px; + margin: 0 16px; +`; + +const VerticalMiddleDiv = styled.div` + border-bottom: 1px solid rgba(239, 239, 239, 1); + margin-bottom: 16px; + padding-bottom: 16px; + display: flex; + align-items: center; +`; + +const StyledSpan = styled.span` + font-size: 14px; +`; + +const InlineH3 = styled.h3` + display: inline-block; + font-size: 18px; + margin-right: 10px; +`; + +const InlineDiv = styled.div` + display: inline-block; +`; + +export default AuthorComment; diff --git a/components/Comment/CommentArea.tsx b/components/Comment/CommentArea.tsx new file mode 100644 index 0000000..fd66e61 --- /dev/null +++ b/components/Comment/CommentArea.tsx @@ -0,0 +1,59 @@ +import { FeedAuthor } from 'types/index'; +import CommentThumbnail from 'components/Comment/CommentThumbnail'; +import styled from '@emotion/styled'; +import React from 'react'; + +export type CommentAreaProps = { + author: FeedAuthor; +}; + +function CommentArea({ author }: CommentAreaProps) { + // Todo : onKeyPressed - enter, onClick 함수구현 + return ( + + + + + 게시 + + + ); +} + +const StyledInput = styled.input` + background-color: transparent; + padding: 0; + height: 18px; + border: 0; + color: rgba(142, 142, 142, 1); +`; + +const StyledForm = styled.form` + align-items: center; + border-radius: 30px; + margin-right: 16px; + padding: 12px 16px; + font-size: 14px; + font-weight: 400; + background-color: rgba(255, 255, 255, 1); + border: 1px solid rgba(219, 219, 219, 1); +`; + +const StyledCommentArea = styled.div` + display: flex; + align-items: center; + background-color: rgba(239, 239, 239, 1); + border-top: 1px solid rgba(219, 219, 219, 1); + border-bottom: 1px solid rgba(219, 219, 219, 1); + padding: 8px 0; +`; + +const StyledSubmitButton = styled.button` + height: 18px; + background-color: transparent; + border: 0; + color: rgba(0, 149, 246, 0.3); + font-size: 14px; +`; + +export default CommentArea; diff --git a/components/Comment/CommentBody.tsx b/components/Comment/CommentBody.tsx new file mode 100644 index 0000000..2a2b470 --- /dev/null +++ b/components/Comment/CommentBody.tsx @@ -0,0 +1,85 @@ +import React, { useState } from 'react'; +import CreatedBottom from 'components/Comment/CommentBottom'; + +import { FeedAuthor, Member } from "types/index"; +import styled from '@emotion/styled'; +import CommentThumbnail from 'components/Comment/CommentThumbnail'; +import Icon from 'components/Icon'; + +export type CommentBodyProps = { + feedAuthor: FeedAuthor; + commentId: number; + content: string; + author: Member; + isLike: Boolean; + likeLength: number; + created: string; +}; + +function CommentBody({ feedAuthor, commentId, content, author, isLike, likeLength, created }: CommentBodyProps) { + const [like, setLike] = useState(isLike); + // Todo: api 구현 + const putLike = () => { + if (like) { + setLike(false); + } else { + setLike(true); + } + }; + // Todo: 조건별 모달 구현 + return ( + <> + + +
+ + +
+ {author.displayId} + {content} +
+ +
+
+
+ + + + + +
+ + ); +} + +const VerticalMiddleDiv = styled.div` + display: flex; + justify-content: space-between; + align-items: center; +`; + +const StyledSpan = styled.span` + font-size: 14px; +`; + +const InlineH3 = styled.h3` + display: inline-block; + font-size: 18px; + margin-right: 10px; +`; + +const InlineDiv = styled.div` + display: inline-block; +`; + +const HeartImg = styled.div` + float: right; +`; + +const StyledButton = styled.button` + display: inline-block; + background-color: transparent; + border: none; +`; + +export default CommentBody; diff --git a/components/Comment/CommentBottom.tsx b/components/Comment/CommentBottom.tsx new file mode 100644 index 0000000..749f0c1 --- /dev/null +++ b/components/Comment/CommentBottom.tsx @@ -0,0 +1,43 @@ +import styled from '@emotion/styled'; +import Created from 'components/Comment/Created'; + +export type CommentBottomProps = { + likeLength: number; + created: string; +}; + +function CommentBottom({ likeLength, created }: CommentBottomProps) { + return ( + <> + + 좋아요 {likeLength}개 + 답글 달기 + + ); +} + +const StyledLikeItem = styled.button` + color: rgba(142, 142, 142, 1); + font-size: 12px; + font-weight: 600; + text-align: center; + border: none; + background-color: transparent; + align-items: flex-start; + box-sizing: border-box; + width: auto; + -webkit-text-size-adjust: 100%; +`; + +const StyledReplyItem = styled.button` + color: rgba(142, 142, 142, 1); + font-size: 12px; + font-weight: 600; + text-align: center; + border: none; + background-color: transparent; + align-items: flex-start; + box-sizing: border-box; +`; + +export default CommentBottom; diff --git a/components/Comment/CommentItem.tsx b/components/Comment/CommentItem.tsx new file mode 100644 index 0000000..41200d2 --- /dev/null +++ b/components/Comment/CommentItem.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { FeedAuthor, Member } from 'types/index'; +import CommentBody from 'components/Comment/CommentBody'; +import ReplyComponent from 'components/Comment/ReplyComponent'; +import styled from '@emotion/styled'; + +export type CommentItemProps = { + feedAuthor: FeedAuthor; + id: number; + content: string; + author: Member; + isLike: Boolean; + likeLength: number; + replyLength: number; + created: string; +}; + +function CommentItem({ feedAuthor, id, content, author, isLike, likeLength, replyLength, created }: CommentItemProps) { + return ( + + + {replyLength > 0 && } + + ); +} + +const Styledli = styled.li` + list-style: none; +`; + +export default CommentItem; diff --git a/components/Comment/CommentNav.tsx b/components/Comment/CommentNav.tsx new file mode 100644 index 0000000..a6d7d28 --- /dev/null +++ b/components/Comment/CommentNav.tsx @@ -0,0 +1,55 @@ +import styled from '@emotion/styled'; +import React from 'react'; +import Icon from 'components/Icon'; + +function CommentNav() { + // Todo: 뒤로가기 구현 + // Todo: DM 으로 이동 구현 + return ( + + + + + + + + + + 댓글 + + + + + + + + ); +} + +const StyledIcon = styled.div` + transform: rotate(-90deg); +`; + +const StyledH1 = styled.h1` + margin-block-start: 0; + margin-block-end: 0; + font-size: 16px; +`; + +const StyledButton = styled.button` + background-color: transparent; + border: 0; +`; + +const StyledDiv = styled.div` + position: relative; + display: block; +`; + +const StyledNav = styled.div` + display: flex; + justify-content: space-between; + flex: 0 0 60px; +`; + +export default CommentNav; diff --git a/components/Comment/CommentThumbnail.tsx b/components/Comment/CommentThumbnail.tsx new file mode 100644 index 0000000..e69a927 --- /dev/null +++ b/components/Comment/CommentThumbnail.tsx @@ -0,0 +1,34 @@ +import styled from '@emotion/styled'; +import { Member } from 'types/index'; +import React from 'react'; + +export type CommentThumbnailProps = { + author: Member; +}; + +function CommentThumbnail({ author }: CommentThumbnailProps) { + return ( + + + + + + ); +} + +const StyledImg = styled.img` + width: 42px; + height: 42px; +`; + +const StyledCommentThumbnail = styled.div` + display: inline-block; + border-radius: 70%; + overflow: hidden; + object-fit: cover; + height: 42px; + width: 42px; + margin: 0 16px; +`; + +export default CommentThumbnail; diff --git a/components/Comment/Created.tsx b/components/Comment/Created.tsx new file mode 100644 index 0000000..f247a54 --- /dev/null +++ b/components/Comment/Created.tsx @@ -0,0 +1,56 @@ +import styled from '@emotion/styled'; +import React from 'react'; + +export type CreatedItemProps = { + currentTime: string; +}; + +function Created({ currentTime }: CreatedItemProps) { + // 지금, 초, 분, 시, 일, 주, 달, 년 + const createdTime = new Date(currentTime); + const now = new Date(Date.now()); + // @ts-ignore + const millisecond = now - createdTime; + const convertedSecond = Math.floor(millisecond / 1000); + const convertedMinute = Math.floor(convertedSecond / 60); + const convertedHour = Math.floor(convertedMinute / 60); + const convertedDay = Math.floor(convertedHour / 24); + const convertedWeek = Math.floor(convertedDay / 7); + const convertedMonth = Math.floor(convertedDay / 30); + const convertedYear = Math.floor(convertedDay / 365); + + let created; + + if (convertedYear >= 1) { + created = `${convertedYear}년`; + } else if (convertedMonth >= 1) { + created = `${convertedMonth}월`; + } else if (convertedWeek >= 1) { + created = `${convertedWeek}주`; + } else if (convertedDay >= 1) { + created = `${convertedDay}일`; + } else if (convertedHour >= 1) { + created = `${convertedHour}시간`; + } else if (convertedMinute >= 1) { + created = `${convertedMinute}분`; + } else if (convertedSecond >= 1) { + created = `${convertedSecond}초`; + } else { + created = '지금'; + } + + return {created}; +} + +const StyledCreatedItem = styled.div` + display: inline-block; + color: rgba(142, 142, 142, 1); + margin-right: 12px; + font-size: 12px; + font-weight: 400; + text-align: left; + border: none; + background-color: transparent; +`; + +export default Created; diff --git a/components/Comment/ReplyComponent.tsx b/components/Comment/ReplyComponent.tsx new file mode 100644 index 0000000..8cc7dde --- /dev/null +++ b/components/Comment/ReplyComponent.tsx @@ -0,0 +1,67 @@ +import styled from '@emotion/styled'; +import React, { useState } from 'react'; +import { Reply } from 'types/index'; + +export type CommentItemProps = { + replySize: number; + commentId: number; // post id +}; + +function ReplyComponent({ replySize, commentId }: CommentItemProps) { + const [show, setShow] = useState(false); + const [replies, setReplies] = useState([]); + const [replyLength, setReplyLength] = useState(replySize); + // Todo : api 구현 + const getReplyList = () => {}; + + return ( + <> + {(show && replyLength > 0) || !show ? ( // 답글 보기 이미 눌림, 남은 답글 있음 +
    + { + setShow(true); + getReplyList(); + }} + > + + 답글 보기({replyLength}개) + +
+ ) : ( + // 답글 보기 이미 눌림, 남은 답글 없음 +
    + setShow(false)}> + + 답글 숨기기 + +
+ )} + + ); +} + +const StyledReply = styled.button` + margin-top: 16px; + margin-left: 28px; + border: none; + background-color: transparent; +`; + +const StyledLine = styled.div` + border-bottom: 1px solid rgba(142, 142, 142, 1); + display: inline-block; + height: 0; + margin-right: 16px; + vertical-align: middle; + width: 24px; +`; + +const StyledCommentReply = styled.span` + color: rgba(142, 142, 142, 1); + font-size: 12px; + font-weight: 600; + text-align: center; +`; + +export default ReplyComponent; diff --git a/components/Comment/comment.stories.tsx b/components/Comment/comment.stories.tsx new file mode 100644 index 0000000..2787604 --- /dev/null +++ b/components/Comment/comment.stories.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import { Story, Meta } from '@storybook/react/types-6-0'; + +import { FeedAuthor, Member, Feed } from 'types'; +import AuthorComment from 'components/Comment/AuthorComment'; +import CommentArea from 'components/Comment/CommentArea'; +import CommentNav from 'components/Comment/CommentNav'; +import CommentItem from './CommentItem'; +import Comment, { CommentsProps } from '.'; +import CommentComponent from "."; + +export default { + title: 'Comment', + component: Comment, +} as Meta; + +const user1: Member = { + displayId: 'hangneu', + nickname: '김하은', + profileImageUrl: + 'https://post-phinf.pstatic.net/MjAxODA3MTlfMTIg/MDAxNTMxOTg5ODE5OTAw.edb-H-Rmhr2dFvKAqKA11flZ2k45cRi4Q4IaHirlMF4g.It6ziXN3vtf0R7B2p9DdwOy1hovG7aynuCPwAysStMcg.JPEG/jy180719b2.jpg?type=w1200', +}; + +const author: FeedAuthor = { + displayId: 'kdongha', + isFollowedByMe: true, + profileImageUrl: + 'https://post-phinf.pstatic.net/MjAxODA3MTlfMTIg/MDAxNTMxOTg5ODE5OTAw.edb-H-Rmhr2dFvKAqKA11flZ2k45cRi4Q4IaHirlMF4g.It6ziXN3vtf0R7B2p9DdwOy1hovG7aynuCPwAysStMcg.JPEG/jy180719b2.jpg?type=w1200', +}; + +const date = '2020-03-26 20:30:11'; + +export const Template: Story = () => ( + <> + + + +
    + +
+ +); diff --git a/components/Comment/index.tsx b/components/Comment/index.tsx new file mode 100644 index 0000000..d2113d8 --- /dev/null +++ b/components/Comment/index.tsx @@ -0,0 +1,39 @@ +import React, { useState } from 'react'; +import Icon from 'components/Icon'; +import { Comment, Feed } from 'types/index'; +import CommentNav from 'components/Comment/CommentNav'; +import CommentArea from 'components/Comment/CommentArea'; +import AuthorComment from 'components/Comment/AuthorComment'; + +export type CommentsProps = { + feed: Feed; + commentSize: number; + postId: number; // post id +}; + +function CommentComponent({ feed, commentSize }: CommentsProps) { + const [feedAuthor, postId, createdAt] = feed; + const [comments, setComments] = useState([]); + const [commentLength, setCommentLength] = useState(commentSize); + // Todo: api 구현 map [] + const getCommentList = () => {}; + return ( + <> + + + + {commentLength > 0 ? ( // 남은 댓글 있음 + <> +
    {comments}
+ + + ) : ( +
    {comments}
+ )} + + ); +} + +export default CommentComponent; diff --git a/components/Icon/svg/index.ts b/components/Icon/svg/index.ts index f118bc8..c183550 100644 --- a/components/Icon/svg/index.ts +++ b/components/Icon/svg/index.ts @@ -8,3 +8,4 @@ export { ReactComponent as share } from './share.svg'; export { ReactComponent as bookmark } from './bookmark.svg'; export { ReactComponent as newpost } from './newpost.svg'; export { ReactComponent as back } from './back.svg'; +export { ReactComponent as plus } from './plus.svg'; diff --git a/components/Icon/svg/plus.svg b/components/Icon/svg/plus.svg new file mode 100644 index 0000000..5194655 --- /dev/null +++ b/components/Icon/svg/plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/types/index.ts b/types/index.ts index 28bd906..1e71da5 100644 --- a/types/index.ts +++ b/types/index.ts @@ -1,10 +1,11 @@ export type Member = { nickname?: string; displayId: string; - profileImageUrl: null | string; + profileImageUrl?: string; }; export type Comment = { + feed: Feed; id: number; content: string; author: Member; @@ -14,6 +15,16 @@ export type Comment = { created: number; // millisecond }; +export type Reply = { + feedAuthor: FeedAuthor; + id: number; + content: string; + author: Member; + isLike: Boolean; + likeLength: number; + created: number; // millisecond +}; + export type FeedAuthor = { displayId: string; isFollowedByMe: boolean; From 158791a9a0201499370218b64736927c630249a7 Mon Sep 17 00:00:00 2001 From: HAEUN KIM Date: Sun, 11 Apr 2021 20:32:24 +0900 Subject: [PATCH 2/7] =?UTF-8?q?[#63]=20form=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Comment/CommentArea.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/Comment/CommentArea.tsx b/components/Comment/CommentArea.tsx index fd66e61..f4c671e 100644 --- a/components/Comment/CommentArea.tsx +++ b/components/Comment/CommentArea.tsx @@ -21,6 +21,8 @@ function CommentArea({ author }: CommentAreaProps) { } const StyledInput = styled.input` + display: flex; + flex-grow: 1; background-color: transparent; padding: 0; height: 18px; @@ -29,6 +31,8 @@ const StyledInput = styled.input` `; const StyledForm = styled.form` + display: flex; + flex-grow: 1; align-items: center; border-radius: 30px; margin-right: 16px; @@ -49,6 +53,8 @@ const StyledCommentArea = styled.div` `; const StyledSubmitButton = styled.button` + display: flex; + justify-content: flex-end; height: 18px; background-color: transparent; border: 0; From 5f00d1f29b061bc831ba73fab58008d6bda276f9 Mon Sep 17 00:00:00 2001 From: HAEUN KIM Date: Sun, 11 Apr 2021 20:44:25 +0900 Subject: [PATCH 3/7] =?UTF-8?q?[#63]=20to=20do=20=EC=A3=BC=EC=84=9D=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Comment/AuthorComment.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/components/Comment/AuthorComment.tsx b/components/Comment/AuthorComment.tsx index b3232c6..726dfe9 100644 --- a/components/Comment/AuthorComment.tsx +++ b/components/Comment/AuthorComment.tsx @@ -10,7 +10,6 @@ export type AuthorCommentProps = { }; function AuthorComment({ content, author, created }: AuthorCommentProps) { - // Todo : form 요소 크기 return ( From c2cd8ea815a4c8f86d5ef5fe58f2f679d46f8d0a Mon Sep 17 00:00:00 2001 From: HAEUN KIM Date: Sun, 11 Apr 2021 23:03:21 +0900 Subject: [PATCH 4/7] =?UTF-8?q?[#63]=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Comment/AuthorComment.tsx | 15 ++++++--- components/Comment/CommentBody.tsx | 16 ++++----- components/Comment/CommentThumbnail.tsx | 9 +++-- components/Comment/Created.tsx | 35 ++------------------ package.json | 1 + utils/api/time.ts | 44 +++++++++++++++++++++++++ yarn.lock | 5 +++ 7 files changed, 74 insertions(+), 51 deletions(-) create mode 100644 utils/api/time.ts diff --git a/components/Comment/AuthorComment.tsx b/components/Comment/AuthorComment.tsx index 726dfe9..c10d9bf 100644 --- a/components/Comment/AuthorComment.tsx +++ b/components/Comment/AuthorComment.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { FeedAuthor } from 'types/index'; import styled from '@emotion/styled'; import Created from 'components/Comment/Created'; +import Link from 'next/link'; export type AuthorCommentProps = { content: string; @@ -9,18 +10,22 @@ export type AuthorCommentProps = { created: string; }; -function AuthorComment({ content, author, created }: AuthorCommentProps) { +function AuthorComment({ content, author: { displayId, profileImageUrl }, created }: AuthorCommentProps) { return ( - - - + + + + +
- {author.displayId} + + {displayId} + {content}
diff --git a/components/Comment/CommentBody.tsx b/components/Comment/CommentBody.tsx index 2a2b470..42668d5 100644 --- a/components/Comment/CommentBody.tsx +++ b/components/Comment/CommentBody.tsx @@ -1,7 +1,7 @@ -import React, { useState } from 'react'; +import React, { useCallback, useState } from 'react'; import CreatedBottom from 'components/Comment/CommentBottom'; -import { FeedAuthor, Member } from "types/index"; +import { FeedAuthor, Member } from 'types/index'; import styled from '@emotion/styled'; import CommentThumbnail from 'components/Comment/CommentThumbnail'; import Icon from 'components/Icon'; @@ -19,13 +19,9 @@ export type CommentBodyProps = { function CommentBody({ feedAuthor, commentId, content, author, isLike, likeLength, created }: CommentBodyProps) { const [like, setLike] = useState(isLike); // Todo: api 구현 - const putLike = () => { - if (like) { - setLike(false); - } else { - setLike(true); - } - }; + const toggleLike = useCallback(() => { + setLike((prev) => !prev); + }, []); // Todo: 조건별 모달 구현 return ( <> @@ -42,7 +38,7 @@ function CommentBody({ feedAuthor, commentId, content, author, isLike, likeLengt
- + diff --git a/components/Comment/CommentThumbnail.tsx b/components/Comment/CommentThumbnail.tsx index e69a927..fa2c6f3 100644 --- a/components/Comment/CommentThumbnail.tsx +++ b/components/Comment/CommentThumbnail.tsx @@ -1,6 +1,7 @@ import styled from '@emotion/styled'; import { Member } from 'types/index'; import React from 'react'; +import Link from 'next/link'; export type CommentThumbnailProps = { author: Member; @@ -9,9 +10,11 @@ export type CommentThumbnailProps = { function CommentThumbnail({ author }: CommentThumbnailProps) { return ( - - - + + + + + ); } diff --git a/components/Comment/Created.tsx b/components/Comment/Created.tsx index f247a54..c6f5223 100644 --- a/components/Comment/Created.tsx +++ b/components/Comment/Created.tsx @@ -1,44 +1,13 @@ import styled from '@emotion/styled'; import React from 'react'; +import { getTimeDiff } from 'utils/api/time'; export type CreatedItemProps = { currentTime: string; }; function Created({ currentTime }: CreatedItemProps) { - // 지금, 초, 분, 시, 일, 주, 달, 년 - const createdTime = new Date(currentTime); - const now = new Date(Date.now()); - // @ts-ignore - const millisecond = now - createdTime; - const convertedSecond = Math.floor(millisecond / 1000); - const convertedMinute = Math.floor(convertedSecond / 60); - const convertedHour = Math.floor(convertedMinute / 60); - const convertedDay = Math.floor(convertedHour / 24); - const convertedWeek = Math.floor(convertedDay / 7); - const convertedMonth = Math.floor(convertedDay / 30); - const convertedYear = Math.floor(convertedDay / 365); - - let created; - - if (convertedYear >= 1) { - created = `${convertedYear}년`; - } else if (convertedMonth >= 1) { - created = `${convertedMonth}월`; - } else if (convertedWeek >= 1) { - created = `${convertedWeek}주`; - } else if (convertedDay >= 1) { - created = `${convertedDay}일`; - } else if (convertedHour >= 1) { - created = `${convertedHour}시간`; - } else if (convertedMinute >= 1) { - created = `${convertedMinute}분`; - } else if (convertedSecond >= 1) { - created = `${convertedSecond}초`; - } else { - created = '지금'; - } - + const created = getTimeDiff(currentTime); return {created}; } diff --git a/package.json b/package.json index d67d276..1a50122 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@emotion/react": "^11.1.5", "@emotion/styled": "^11.1.5", "axios": "^0.21.1", + "date-fns": "^2.20.1", "eslint": "^7.23.0", "next": "latest", "next-images": "^1.7.0", diff --git a/utils/api/time.ts b/utils/api/time.ts new file mode 100644 index 0000000..b9a5ec8 --- /dev/null +++ b/utils/api/time.ts @@ -0,0 +1,44 @@ +import { + differenceInYears, + differenceInMonths, + differenceInWeeks, + differenceInDays, + differenceInHours, + differenceInMinutes, + differenceInSeconds, +} from 'date-fns'; + +export const getTimeDiff = (currentTime: string) => { + // 지금, 초, 분, 시, 일, 주, 달, 년 + const createdTime = new Date(currentTime); + const now = new Date(Date.now()); + const convertedSecond = differenceInSeconds(createdTime, now); + const convertedMinute = differenceInMinutes(createdTime, now); + const convertedHour = differenceInHours(createdTime, now); + const convertedDay = differenceInDays(createdTime, now); + const convertedWeek = differenceInWeeks(createdTime, now); + const convertedMonth = differenceInMonths(createdTime, now); + const convertedYear = differenceInYears(createdTime, now); + + let created; + + if (convertedYear >= 1) { + created = `${convertedYear}년`; + } else if (convertedMonth >= 1) { + created = `${convertedMonth}월`; + } else if (convertedWeek >= 1) { + created = `${convertedWeek}주`; + } else if (convertedDay >= 1) { + created = `${convertedDay}일`; + } else if (convertedHour >= 1) { + created = `${convertedHour}시간`; + } else if (convertedMinute >= 1) { + created = `${convertedMinute}분`; + } else if (convertedSecond >= 1) { + created = `${convertedSecond}초`; + } else { + created = '지금'; + } + + return created; +}; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 0722a3c..83b934b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4546,6 +4546,11 @@ data-uri-to-buffer@3.0.1: resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== +date-fns@^2.20.1: + version "2.20.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.20.1.tgz#7e60b7035284a5f83e37500376e738d9f49ecfd3" + integrity sha512-8P5M8Kxbnovd0zfvOs7ipkiVJ3/zZQ0F/nrBW4x5E+I0uAZVZ80h6CKd24fSXQ5TLK5hXMtI4yb2O5rEZdUt2A== + debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" From 1c797dedff98f533a7d682fb8e26505a8993662f Mon Sep 17 00:00:00 2001 From: HAEUN KIM Date: Thu, 15 Apr 2021 16:35:04 +0900 Subject: [PATCH 5/7] =?UTF-8?q?[#63]=20CommentThumbnail=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C,=20=EB=A7=81=ED=81=AC=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Comment/AuthorComment.tsx | 38 +++++------- components/Comment/CommentArea.tsx | 33 ++++++----- components/Comment/CommentBody.tsx | 78 ++++++++++++++++--------- components/Comment/CommentBottom.tsx | 11 ++-- components/Comment/CommentThumbnail.tsx | 37 ------------ components/Comment/Created.tsx | 3 +- components/Comment/ReplyComponent.tsx | 18 +++--- components/Comment/comment.stories.tsx | 3 +- components/Comment/index.tsx | 6 +- 9 files changed, 107 insertions(+), 120 deletions(-) delete mode 100644 components/Comment/CommentThumbnail.tsx diff --git a/components/Comment/AuthorComment.tsx b/components/Comment/AuthorComment.tsx index c10d9bf..edb055a 100644 --- a/components/Comment/AuthorComment.tsx +++ b/components/Comment/AuthorComment.tsx @@ -3,6 +3,7 @@ import { FeedAuthor } from 'types/index'; import styled from '@emotion/styled'; import Created from 'components/Comment/Created'; import Link from 'next/link'; +import UserAvatar from 'components/UserAvatar'; export type AuthorCommentProps = { content: string; @@ -13,18 +14,15 @@ export type AuthorCommentProps = { function AuthorComment({ content, author: { displayId, profileImageUrl }, created }: AuthorCommentProps) { return ( - - - - - - - + + + +
- {displayId} + {displayId} {content} @@ -35,28 +33,13 @@ function AuthorComment({ content, author: { displayId, profileImageUrl }, create ); } -const StyledAtag = styled.a` +const StyledAnchor = styled.a` text-decoration: none; color: inherit; `; -const StyledImg = styled.img` - height: 42px; - width: 42px; -`; - -const StyledCommentThumbnail = styled.div` - display: inline-block; - border-radius: 70%; - overflow: hidden; - object-fit: cover; - height: 42px; - width: 42px; - margin: 0 16px; -`; - const VerticalMiddleDiv = styled.div` - border-bottom: 1px solid rgba(239, 239, 239, 1); + border-bottom: 1px solid rgb(239, 239, 239); margin-bottom: 16px; padding-bottom: 16px; display: flex; @@ -73,6 +56,11 @@ const InlineH3 = styled.h3` margin-right: 10px; `; +const ThumbnailDiv = styled.div` + display: inline-block; + margin: 0 16px; +`; + const InlineDiv = styled.div` display: inline-block; `; diff --git a/components/Comment/CommentArea.tsx b/components/Comment/CommentArea.tsx index f4c671e..7d3261a 100644 --- a/components/Comment/CommentArea.tsx +++ b/components/Comment/CommentArea.tsx @@ -1,33 +1,40 @@ -import { FeedAuthor } from 'types/index'; -import CommentThumbnail from 'components/Comment/CommentThumbnail'; +import { Member } from 'types/index'; import styled from '@emotion/styled'; import React from 'react'; +import UserAvatar from 'components/UserAvatar'; export type CommentAreaProps = { - author: FeedAuthor; + author: Member; }; -function CommentArea({ author }: CommentAreaProps) { +function CommentArea({ author: { profileImageUrl } }: CommentAreaProps) { // Todo : onKeyPressed - enter, onClick 함수구현 return ( - + + + - + 게시 ); } -const StyledInput = styled.input` +const InlineDiv = styled.div` + display: inline-block; + margin: 0 16px; +`; + +const StyledTextArea = styled.textarea` display: flex; flex-grow: 1; background-color: transparent; padding: 0; height: 18px; border: 0; - color: rgba(142, 142, 142, 1); + color: rgb(142, 142, 142); `; const StyledForm = styled.form` @@ -39,16 +46,16 @@ const StyledForm = styled.form` padding: 12px 16px; font-size: 14px; font-weight: 400; - background-color: rgba(255, 255, 255, 1); - border: 1px solid rgba(219, 219, 219, 1); + background-color: rgb(255, 255, 255); + border: 1px solid rgb(219, 219, 219); `; const StyledCommentArea = styled.div` display: flex; align-items: center; - background-color: rgba(239, 239, 239, 1); - border-top: 1px solid rgba(219, 219, 219, 1); - border-bottom: 1px solid rgba(219, 219, 219, 1); + background-color: rgb(239, 239, 239); + border-top: 1px solid rgb(219, 219, 219); + border-bottom: 1px solid rgb(219, 219, 219); padding: 8px 0; `; diff --git a/components/Comment/CommentBody.tsx b/components/Comment/CommentBody.tsx index 42668d5..883dda7 100644 --- a/components/Comment/CommentBody.tsx +++ b/components/Comment/CommentBody.tsx @@ -3,8 +3,9 @@ import CreatedBottom from 'components/Comment/CommentBottom'; import { FeedAuthor, Member } from 'types/index'; import styled from '@emotion/styled'; -import CommentThumbnail from 'components/Comment/CommentThumbnail'; import Icon from 'components/Icon'; +import UserAvatar from 'components/UserAvatar'; +import Link from 'next/link'; export type CommentBodyProps = { feedAuthor: FeedAuthor; @@ -16,7 +17,15 @@ export type CommentBodyProps = { created: string; }; -function CommentBody({ feedAuthor, commentId, content, author, isLike, likeLength, created }: CommentBodyProps) { +function CommentBody({ + feedAuthor, + commentId, + content, + author: { displayId, profileImageUrl }, + isLike, + likeLength, + created, +}: CommentBodyProps) { const [like, setLike] = useState(isLike); // Todo: api 구현 const toggleLike = useCallback(() => { @@ -24,37 +33,55 @@ function CommentBody({ feedAuthor, commentId, content, author, isLike, likeLengt }, []); // Todo: 조건별 모달 구현 return ( - <> + + + + -
- - -
- {author.displayId} - {content} -
- -
-
+ + + {displayId} + + + {content} +
- - - - -
- + + + +
); } +const InlineDiv = styled.div` + display: inline-block; +`; + +const StyledDiv = styled.div` + display: flex; +`; + +const StyledAnchor = styled.a` + text-decoration: none; + color: inherit; +`; + +const ThumbnailDiv = styled.div` + display: inline-block; + vertical-align: middle; + margin: 0 16px; +`; + const VerticalMiddleDiv = styled.div` display: flex; - justify-content: space-between; + flex-grow: 1; align-items: center; `; const StyledSpan = styled.span` + display: inline-block; font-size: 14px; `; @@ -64,16 +91,9 @@ const InlineH3 = styled.h3` margin-right: 10px; `; -const InlineDiv = styled.div` - display: inline-block; -`; - -const HeartImg = styled.div` - float: right; -`; - const StyledButton = styled.button` - display: inline-block; + display: flex; + align-items: center; background-color: transparent; border: none; `; diff --git a/components/Comment/CommentBottom.tsx b/components/Comment/CommentBottom.tsx index 749f0c1..61ab69a 100644 --- a/components/Comment/CommentBottom.tsx +++ b/components/Comment/CommentBottom.tsx @@ -8,16 +8,19 @@ export type CommentBottomProps = { function CommentBottom({ likeLength, created }: CommentBottomProps) { return ( - <> + 좋아요 {likeLength}개 답글 달기 - + ); } +const StyledDiv = styled.div` + display: flex; +`; const StyledLikeItem = styled.button` - color: rgba(142, 142, 142, 1); + color: rgb(142, 142, 142); font-size: 12px; font-weight: 600; text-align: center; @@ -30,7 +33,7 @@ const StyledLikeItem = styled.button` `; const StyledReplyItem = styled.button` - color: rgba(142, 142, 142, 1); + color: rgb(142, 142, 142); font-size: 12px; font-weight: 600; text-align: center; diff --git a/components/Comment/CommentThumbnail.tsx b/components/Comment/CommentThumbnail.tsx deleted file mode 100644 index fa2c6f3..0000000 --- a/components/Comment/CommentThumbnail.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import styled from '@emotion/styled'; -import { Member } from 'types/index'; -import React from 'react'; -import Link from 'next/link'; - -export type CommentThumbnailProps = { - author: Member; -}; - -function CommentThumbnail({ author }: CommentThumbnailProps) { - return ( - - - - - - - - ); -} - -const StyledImg = styled.img` - width: 42px; - height: 42px; -`; - -const StyledCommentThumbnail = styled.div` - display: inline-block; - border-radius: 70%; - overflow: hidden; - object-fit: cover; - height: 42px; - width: 42px; - margin: 0 16px; -`; - -export default CommentThumbnail; diff --git a/components/Comment/Created.tsx b/components/Comment/Created.tsx index c6f5223..5d7acb6 100644 --- a/components/Comment/Created.tsx +++ b/components/Comment/Created.tsx @@ -13,7 +13,8 @@ function Created({ currentTime }: CreatedItemProps) { const StyledCreatedItem = styled.div` display: inline-block; - color: rgba(142, 142, 142, 1); + justify-content: space-between; + color: rgb(142, 142, 142); margin-right: 12px; font-size: 12px; font-weight: 400; diff --git a/components/Comment/ReplyComponent.tsx b/components/Comment/ReplyComponent.tsx index 8cc7dde..8e12b46 100644 --- a/components/Comment/ReplyComponent.tsx +++ b/components/Comment/ReplyComponent.tsx @@ -13,16 +13,20 @@ function ReplyComponent({ replySize, commentId }: CommentItemProps) { const [replyLength, setReplyLength] = useState(replySize); // Todo : api 구현 const getReplyList = () => {}; + const openReply = () => { + setShow(true); + getReplyList(); + }; + const closeReply = () => { + setShow(false); + } return ( <> {(show && replyLength > 0) || !show ? ( // 답글 보기 이미 눌림, 남은 답글 있음
    { - setShow(true); - getReplyList(); - }} + onClick={openReply} > 답글 보기({replyLength}개) @@ -31,7 +35,7 @@ function ReplyComponent({ replySize, commentId }: CommentItemProps) { ) : ( // 답글 보기 이미 눌림, 남은 답글 없음
      - setShow(false)}> + 답글 숨기기 @@ -49,7 +53,7 @@ const StyledReply = styled.button` `; const StyledLine = styled.div` - border-bottom: 1px solid rgba(142, 142, 142, 1); + border-bottom: 1px solid rgb(142, 142, 142); display: inline-block; height: 0; margin-right: 16px; @@ -58,7 +62,7 @@ const StyledLine = styled.div` `; const StyledCommentReply = styled.span` - color: rgba(142, 142, 142, 1); + color: rgb(142, 142, 142); font-size: 12px; font-weight: 600; text-align: center; diff --git a/components/Comment/comment.stories.tsx b/components/Comment/comment.stories.tsx index 2787604..668fb87 100644 --- a/components/Comment/comment.stories.tsx +++ b/components/Comment/comment.stories.tsx @@ -1,13 +1,12 @@ import React from 'react'; import { Story, Meta } from '@storybook/react/types-6-0'; -import { FeedAuthor, Member, Feed } from 'types'; +import { FeedAuthor, Member } from 'types'; import AuthorComment from 'components/Comment/AuthorComment'; import CommentArea from 'components/Comment/CommentArea'; import CommentNav from 'components/Comment/CommentNav'; import CommentItem from './CommentItem'; import Comment, { CommentsProps } from '.'; -import CommentComponent from "."; export default { title: 'Comment', diff --git a/components/Comment/index.tsx b/components/Comment/index.tsx index d2113d8..f4c7dbc 100644 --- a/components/Comment/index.tsx +++ b/components/Comment/index.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import Icon from 'components/Icon'; -import { Comment, Feed } from 'types/index'; +import { Comment, Feed, Member } from 'types/index'; import CommentNav from 'components/Comment/CommentNav'; import CommentArea from 'components/Comment/CommentArea'; import AuthorComment from 'components/Comment/AuthorComment'; @@ -16,11 +16,13 @@ function CommentComponent({ feed, commentSize }: CommentsProps) { const [comments, setComments] = useState([]); const [commentLength, setCommentLength] = useState(commentSize); // Todo: api 구현 map [] + // Todo: context Api로 me 변수 만들기 const getCommentList = () => {}; return ( <> - + + {commentLength > 0 ? ( // 남은 댓글 있음 <> From 09643b5a0168a3feb618bebc46c10f67c4ff3ac3 Mon Sep 17 00:00:00 2001 From: HAEUN KIM Date: Thu, 15 Apr 2021 21:47:12 +0900 Subject: [PATCH 6/7] =?UTF-8?q?[#63]=20=EC=A3=BC=EC=84=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Comment/AuthorComment.tsx | 2 +- components/Comment/index.tsx | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/components/Comment/AuthorComment.tsx b/components/Comment/AuthorComment.tsx index edb055a..bd0a527 100644 --- a/components/Comment/AuthorComment.tsx +++ b/components/Comment/AuthorComment.tsx @@ -14,7 +14,7 @@ export type AuthorCommentProps = { function AuthorComment({ content, author: { displayId, profileImageUrl }, created }: AuthorCommentProps) { return ( - + {/*-- Todo: UserAvatar에 링크달기 */ } diff --git a/components/Comment/index.tsx b/components/Comment/index.tsx index f4c7dbc..8f334d2 100644 --- a/components/Comment/index.tsx +++ b/components/Comment/index.tsx @@ -1,8 +1,7 @@ import React, { useState } from 'react'; import Icon from 'components/Icon'; -import { Comment, Feed, Member } from 'types/index'; +import { Comment, Feed } from 'types/index'; import CommentNav from 'components/Comment/CommentNav'; -import CommentArea from 'components/Comment/CommentArea'; import AuthorComment from 'components/Comment/AuthorComment'; export type CommentsProps = { @@ -21,8 +20,7 @@ function CommentComponent({ feed, commentSize }: CommentsProps) { return ( <> - - + {/* CommentArea author = {me} */} {commentLength > 0 ? ( // 남은 댓글 있음 <> From d68a10e87e3c322d94e1172acdef364364f01a08 Mon Sep 17 00:00:00 2001 From: HAEUN KIM Date: Fri, 16 Apr 2021 02:26:23 +0900 Subject: [PATCH 7/7] =?UTF-8?q?[#63]=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Comment/AuthorComment.tsx | 32 ++++++++------ .../Comment/{CommentBody.tsx => Body.tsx} | 30 +++++-------- components/Comment/CommentArea.tsx | 1 + components/Comment/CommentBottom.tsx | 18 +++++++- components/Comment/CommentItem.tsx | 26 +++++------- components/Comment/CommentNav.tsx | 11 ++--- components/Comment/Created.tsx | 26 ------------ components/Comment/ReplyComponent.tsx | 42 +++++++++---------- components/Comment/ReplyItem.tsx | 32 ++++++++++++++ components/Comment/comment.stories.tsx | 27 ++++++------ components/Comment/index.tsx | 25 +++++------ types/index.ts | 8 ++-- utils/api/time.ts | 39 ++++++++--------- 13 files changed, 159 insertions(+), 158 deletions(-) rename components/Comment/{CommentBody.tsx => Body.tsx} (76%) delete mode 100644 components/Comment/Created.tsx create mode 100644 components/Comment/ReplyItem.tsx diff --git a/components/Comment/AuthorComment.tsx b/components/Comment/AuthorComment.tsx index bd0a527..d9766fb 100644 --- a/components/Comment/AuthorComment.tsx +++ b/components/Comment/AuthorComment.tsx @@ -1,9 +1,8 @@ import React from 'react'; import { FeedAuthor } from 'types/index'; import styled from '@emotion/styled'; -import Created from 'components/Comment/Created'; -import Link from 'next/link'; import UserAvatar from 'components/UserAvatar'; +import { getTimeDiff } from 'utils/api/time'; export type AuthorCommentProps = { content: string; @@ -14,25 +13,36 @@ export type AuthorCommentProps = { function AuthorComment({ content, author: { displayId, profileImageUrl }, created }: AuthorCommentProps) { return ( - {/*-- Todo: UserAvatar에 링크달기 */ } + {/* Todo: UserAvatar에 링크달기 */} - +
      - - {displayId} - + {/* Todo: displayId에 링크 달기 */} + {displayId} {content}
      - - + {getTimeDiff(created)} +
      ); } +const StyledCreatedItem = styled.div` + display: inline-block; + justify-content: space-between; + color: rgb(142, 142, 142); + margin-right: 12px; + font-size: 12px; + font-weight: 400; + text-align: left; + border: none; + background-color: transparent; +`; + const StyledAnchor = styled.a` text-decoration: none; color: inherit; @@ -61,8 +71,4 @@ const ThumbnailDiv = styled.div` margin: 0 16px; `; -const InlineDiv = styled.div` - display: inline-block; -`; - export default AuthorComment; diff --git a/components/Comment/CommentBody.tsx b/components/Comment/Body.tsx similarity index 76% rename from components/Comment/CommentBody.tsx rename to components/Comment/Body.tsx index 883dda7..73f87ab 100644 --- a/components/Comment/CommentBody.tsx +++ b/components/Comment/Body.tsx @@ -1,15 +1,14 @@ import React, { useCallback, useState } from 'react'; import CreatedBottom from 'components/Comment/CommentBottom'; -import { FeedAuthor, Member } from 'types/index'; +import { Member } from 'types/index'; import styled from '@emotion/styled'; import Icon from 'components/Icon'; import UserAvatar from 'components/UserAvatar'; -import Link from 'next/link'; -export type CommentBodyProps = { - feedAuthor: FeedAuthor; - commentId: number; +export type BodyProps = { + feedAuthorDisplayId: string; + id: number; content: string; author: Member; isLike: Boolean; @@ -17,21 +16,13 @@ export type CommentBodyProps = { created: string; }; -function CommentBody({ - feedAuthor, - commentId, - content, - author: { displayId, profileImageUrl }, - isLike, - likeLength, - created, -}: CommentBodyProps) { +function Body({ feedAuthorDisplayId, id, content, author:{displayId, profileImageUrl}, isLike, likeLength, created }: BodyProps) { const [like, setLike] = useState(isLike); - // Todo: api 구현 + // Todo: api 구현, comment id 필요 const toggleLike = useCallback(() => { setLike((prev) => !prev); }, []); - // Todo: 조건별 모달 구현 + // Todo: 조건별 모달 구현, feedAuthor displayId 필요 return ( @@ -40,9 +31,8 @@ function CommentBody({ - - {displayId} - + {/* Todo: displayId link 걸기 */} + {displayId} {content} @@ -98,4 +88,4 @@ const StyledButton = styled.button` border: none; `; -export default CommentBody; +export default Body; diff --git a/components/Comment/CommentArea.tsx b/components/Comment/CommentArea.tsx index 7d3261a..4a06b9d 100644 --- a/components/Comment/CommentArea.tsx +++ b/components/Comment/CommentArea.tsx @@ -29,6 +29,7 @@ const InlineDiv = styled.div` const StyledTextArea = styled.textarea` display: flex; + resize: none; flex-grow: 1; background-color: transparent; padding: 0; diff --git a/components/Comment/CommentBottom.tsx b/components/Comment/CommentBottom.tsx index 61ab69a..5812c87 100644 --- a/components/Comment/CommentBottom.tsx +++ b/components/Comment/CommentBottom.tsx @@ -1,5 +1,6 @@ import styled from '@emotion/styled'; -import Created from 'components/Comment/Created'; +import { getTimeDiff } from 'utils/api/time'; +import React from 'react'; export type CommentBottomProps = { likeLength: number; @@ -9,12 +10,25 @@ export type CommentBottomProps = { function CommentBottom({ likeLength, created }: CommentBottomProps) { return ( - + {getTimeDiff(created)} 좋아요 {likeLength}개 답글 달기 ); } + +const StyledCreatedItem = styled.div` + display: inline-block; + justify-content: space-between; + color: rgb(142, 142, 142); + margin-right: 12px; + font-size: 12px; + font-weight: 400; + text-align: left; + border: none; + background-color: transparent; +`; + const StyledDiv = styled.div` display: flex; `; diff --git a/components/Comment/CommentItem.tsx b/components/Comment/CommentItem.tsx index 41200d2..f4709fe 100644 --- a/components/Comment/CommentItem.tsx +++ b/components/Comment/CommentItem.tsx @@ -1,31 +1,25 @@ import React from 'react'; -import { FeedAuthor, Member } from 'types/index'; -import CommentBody from 'components/Comment/CommentBody'; +import { Comment } from 'types/index'; +import Body from 'components/Comment/Body'; import ReplyComponent from 'components/Comment/ReplyComponent'; import styled from '@emotion/styled'; export type CommentItemProps = { - feedAuthor: FeedAuthor; - id: number; - content: string; - author: Member; - isLike: Boolean; - likeLength: number; - replyLength: number; - created: string; + comment: Comment; }; -function CommentItem({ feedAuthor, id, content, author, isLike, likeLength, replyLength, created }: CommentItemProps) { +function CommentItem({ comment }: CommentItemProps) { + const { replyLength, id, feedAuthorDisplayId, likeLength, isLike, created, content, author } = comment; return ( - {replyLength > 0 && } diff --git a/components/Comment/CommentNav.tsx b/components/Comment/CommentNav.tsx index a6d7d28..283cb09 100644 --- a/components/Comment/CommentNav.tsx +++ b/components/Comment/CommentNav.tsx @@ -8,11 +8,9 @@ function CommentNav() { return ( - - - - - + + + 댓글 @@ -26,7 +24,7 @@ function CommentNav() { ); } -const StyledIcon = styled.div` +const StyledIcon = styled.button` transform: rotate(-90deg); `; @@ -43,7 +41,6 @@ const StyledButton = styled.button` const StyledDiv = styled.div` position: relative; - display: block; `; const StyledNav = styled.div` diff --git a/components/Comment/Created.tsx b/components/Comment/Created.tsx deleted file mode 100644 index 5d7acb6..0000000 --- a/components/Comment/Created.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import styled from '@emotion/styled'; -import React from 'react'; -import { getTimeDiff } from 'utils/api/time'; - -export type CreatedItemProps = { - currentTime: string; -}; - -function Created({ currentTime }: CreatedItemProps) { - const created = getTimeDiff(currentTime); - return {created}; -} - -const StyledCreatedItem = styled.div` - display: inline-block; - justify-content: space-between; - color: rgb(142, 142, 142); - margin-right: 12px; - font-size: 12px; - font-weight: 400; - text-align: left; - border: none; - background-color: transparent; -`; - -export default Created; diff --git a/components/Comment/ReplyComponent.tsx b/components/Comment/ReplyComponent.tsx index 8e12b46..6e315b0 100644 --- a/components/Comment/ReplyComponent.tsx +++ b/components/Comment/ReplyComponent.tsx @@ -1,10 +1,10 @@ import styled from '@emotion/styled'; -import React, { useState } from 'react'; +import React, { useCallback, useState } from 'react'; import { Reply } from 'types/index'; export type CommentItemProps = { replySize: number; - commentId: number; // post id + commentId: number; }; function ReplyComponent({ replySize, commentId }: CommentItemProps) { @@ -13,35 +13,31 @@ function ReplyComponent({ replySize, commentId }: CommentItemProps) { const [replyLength, setReplyLength] = useState(replySize); // Todo : api 구현 const getReplyList = () => {}; - const openReply = () => { + const openReply = useCallback(() => { setShow(true); getReplyList(); - }; - const closeReply = () => { + }, []); + const closeReply = useCallback(() => { setShow(false); - } + }, []); + const showReply = (show && replyLength > 0) || !show; return ( - <> - {(show && replyLength > 0) || !show ? ( // 답글 보기 이미 눌림, 남은 답글 있음 -
        - - - 답글 보기({replyLength}개) - -
      +
        + {showReply ? ( // 답글 보기 이미 눌림, 남은 답글 있음 + + + 답글 보기({replyLength}개) + ) : ( // 답글 보기 이미 눌림, 남은 답글 없음 -
          - - - 답글 숨기기 - -
        + + + 답글 숨기기 + )} - + {replies} +
      ); } diff --git a/components/Comment/ReplyItem.tsx b/components/Comment/ReplyItem.tsx new file mode 100644 index 0000000..64c87d6 --- /dev/null +++ b/components/Comment/ReplyItem.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import { Reply } from 'types/index'; +import styled from '@emotion/styled'; +import Body from 'components/Comment/Body'; + +export type ReplyItemProps = { + reply: Reply; +}; + +function ReplyItem({ + reply: { feedAuthorDisplayId, author, content, created, id, isLike, likeLength }, +}: ReplyItemProps) { + return ( + + + + ); +} + +const Styledli = styled.li` + list-style: none; +`; + +export default ReplyItem; diff --git a/components/Comment/comment.stories.tsx b/components/Comment/comment.stories.tsx index 668fb87..1b299b4 100644 --- a/components/Comment/comment.stories.tsx +++ b/components/Comment/comment.stories.tsx @@ -1,16 +1,16 @@ import React from 'react'; import { Story, Meta } from '@storybook/react/types-6-0'; -import { FeedAuthor, Member } from 'types'; +import { FeedAuthor, Member, Comment } from 'types'; import AuthorComment from 'components/Comment/AuthorComment'; import CommentArea from 'components/Comment/CommentArea'; import CommentNav from 'components/Comment/CommentNav'; import CommentItem from './CommentItem'; -import Comment, { CommentsProps } from '.'; +import CommentComponent , { CommentsProps } from '.'; export default { title: 'Comment', - component: Comment, + component: CommentComponent, } as Meta; const user1: Member = { @@ -28,6 +28,16 @@ const author: FeedAuthor = { }; const date = '2020-03-26 20:30:11'; +const comment: Comment = { + feedAuthorDisplayId: author.displayId, + id: 1, + author: user1, + created: date, + isLike: true, + replyLength: 1, + content: '킹동하 팬이에요!', + likeLength: 3, +}; export const Template: Story = () => ( <> @@ -35,16 +45,7 @@ export const Template: Story = () => (
        - +
      ); diff --git a/components/Comment/index.tsx b/components/Comment/index.tsx index 8f334d2..d5247d8 100644 --- a/components/Comment/index.tsx +++ b/components/Comment/index.tsx @@ -6,31 +6,26 @@ import AuthorComment from 'components/Comment/AuthorComment'; export type CommentsProps = { feed: Feed; - commentSize: number; - postId: number; // post id }; -function CommentComponent({ feed, commentSize }: CommentsProps) { - const [feedAuthor, postId, createdAt] = feed; +function CommentComponent({ feed }: CommentsProps) { + const { author, id, createdAt, body, commentLength: defaultCommentLength } = feed; const [comments, setComments] = useState([]); - const [commentLength, setCommentLength] = useState(commentSize); + const [commentLength, setCommentLength] = useState(defaultCommentLength); // Todo: api 구현 map [] // Todo: context Api로 me 변수 만들기 const getCommentList = () => {}; + const moreComment = commentLength > 0; return ( <> {/* CommentArea author = {me} */} - - {commentLength > 0 ? ( // 남은 댓글 있음 - <> -
        {comments}
      - - - ) : ( -
        {comments}
      + +
        {comments}
      + {moreComment && ( // 남은 댓글 있음 + )} ); diff --git a/types/index.ts b/types/index.ts index 1e71da5..37ed380 100644 --- a/types/index.ts +++ b/types/index.ts @@ -5,24 +5,24 @@ export type Member = { }; export type Comment = { - feed: Feed; + feedAuthorDisplayId: string; id: number; content: string; author: Member; isLike: Boolean; likeLength: number; replyLength: number; - created: number; // millisecond + created: string; }; export type Reply = { - feedAuthor: FeedAuthor; + feedAuthorDisplayId: string; id: number; content: string; author: Member; isLike: Boolean; likeLength: number; - created: number; // millisecond + created: string; }; export type FeedAuthor = { diff --git a/utils/api/time.ts b/utils/api/time.ts index b9a5ec8..3ba622a 100644 --- a/utils/api/time.ts +++ b/utils/api/time.ts @@ -20,25 +20,26 @@ export const getTimeDiff = (currentTime: string) => { const convertedMonth = differenceInMonths(createdTime, now); const convertedYear = differenceInYears(createdTime, now); - let created; - if (convertedYear >= 1) { - created = `${convertedYear}년`; - } else if (convertedMonth >= 1) { - created = `${convertedMonth}월`; - } else if (convertedWeek >= 1) { - created = `${convertedWeek}주`; - } else if (convertedDay >= 1) { - created = `${convertedDay}일`; - } else if (convertedHour >= 1) { - created = `${convertedHour}시간`; - } else if (convertedMinute >= 1) { - created = `${convertedMinute}분`; - } else if (convertedSecond >= 1) { - created = `${convertedSecond}초`; - } else { - created = '지금'; + return `${convertedYear}년`; } - - return created; + if (convertedMonth >= 1) { + return `${convertedMonth}월`; + } + if (convertedWeek >= 1) { + return `${convertedWeek}주`; + } + if (convertedDay >= 1) { + return `${convertedDay}일`; + } + if (convertedHour >= 1) { + return `${convertedHour}시간`; + } + if (convertedMinute >= 1) { + return `${convertedMinute}분`; + } + if (convertedSecond >= 1) { + return `${convertedSecond}초`; + } + return '지금'; }; \ No newline at end of file