Skip to content

Commit

Permalink
feat: 모임 피드 상세 뷰 UI 수정 (#606)
Browse files Browse the repository at this point in the history
* feat: 댓글 입력 placeholder 변경

* feat: 좋아요 영역 hover 처리

* feat: 댓글 수 표시 영역을 버튼으로 spec 변경, 댓글 버튼 클릭 시 댓글 textarea 포커스

* feat: 더보기 버튼 왼쪽에 공유 버튼 추가 (클릭 시 토스트 메시지 등장)

* chore: color 및 크기 수정

* feat: hover 시 버튼 처리

* chore: textarea focus 시 처리

* feat: 모임 정보 안내 버튼 추가

* feat: 모임 정보 안내 버튼 안에 아이콘 추가

* feat: 모임 소개 말줄임 처리

* refactor: 코드 리뷰 반영

* feat: 댓글 입력 부분 디자인 수정사항 반영
  • Loading branch information
100Gyeon authored Dec 9, 2023
1 parent b023254 commit 9509293
Show file tree
Hide file tree
Showing 10 changed files with 271 additions and 75 deletions.
20 changes: 18 additions & 2 deletions pages/post/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ import { styled } from 'stitches.config';
import FeedEditModal from '@components/feed/Modal/FeedEditModal';
import { ampli } from '@/ampli';
import { useQueryGetMeeting } from '@api/meeting/hooks';
import React from 'react';
import React, { useRef } from 'react';
import { useDisplay } from '@hooks/useDisplay';
import FeedItem from '@components/page/meetingDetail/Feed/FeedItem';
import Link from 'next/link';

export default function PostPage() {
const commentRef = useRef<HTMLTextAreaElement | null>(null);
const overlay = useOverlay();
const showToast = useToast();
const router = useRouter();
Expand Down Expand Up @@ -96,6 +97,13 @@ export default function PostPage() {
!!comment
);

const handleClickComment = () => {
const refCurrent = commentRef.current;
if (refCurrent) {
refCurrent.focus();
}
};

const handleClickPostLike = () => {
ampli.clickFeeddetailLike({ crew_status: meeting?.approved });
togglePostLike();
Expand Down Expand Up @@ -166,6 +174,7 @@ export default function PostPage() {
isLiked={post.isLiked}
commentCount={commentQuery.data?.pages[0].data?.data?.meta.itemCount || 0}
likeCount={post.likeCount}
onClickComment={handleClickComment}
onClickLike={handleClickPostLike}
/>
}
Expand All @@ -183,7 +192,14 @@ export default function PostPage() {
{commentQuery.hasNextPage && <div ref={setTarget} />}
</>
}
CommentInput={<FeedCommentInput onSubmit={handleCreateComment} disabled={isCreatingComment} />}
CommentInput={
<FeedCommentInput
ref={commentRef}
writerName={post.user.name}
onSubmit={handleCreateComment}
disabled={isCreatingComment}
/>
}
onClickImage={() => {
ampli.clickFeeddetailLike({ crew_status: meeting?.approved });
}}
Expand Down
3 changes: 3 additions & 0 deletions public/assets/svg/arrow_card.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions public/assets/svg/comment_hover.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/assets/svg/like_hover.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 3 additions & 12 deletions public/assets/svg/send.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/assets/svg/send_fill.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/assets/svg/share.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
97 changes: 62 additions & 35 deletions src/components/feed/FeedCommentInput/FeedCommentInput.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,79 @@
import { styled } from 'stitches.config';
import SendIcon from 'public/assets/svg/send.svg';
import React, { useState } from 'react';
import SendFillIcon from 'public/assets/svg/send_fill.svg';
import React, { forwardRef, useState } from 'react';

interface FeedCommentInputProps {
writerName: string;
onSubmit: (comment: string) => Promise<void>;
disabled?: boolean;
}

export default function FeedCommentInput({ onSubmit, disabled }: FeedCommentInputProps) {
const [comment, setComment] = useState('');
const FeedCommentInput = forwardRef<HTMLTextAreaElement, FeedCommentInputProps>(
({ writerName, onSubmit, disabled }, ref) => {
const [comment, setComment] = useState('');
const [isFocused, setIsFocused] = useState(false);

const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
if (e.target.value.length === 0) {
e.target.style.height = 'auto';
} else {
e.target.style.height = `${e.target.scrollHeight}px`;
}
setComment(e.target.value);
};
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
if (e.target.value.length === 0) {
e.target.style.height = 'auto';
} else {
e.target.style.height = `${e.target.scrollHeight}px`;
}
setComment(e.target.value);
};

const handleSubmit = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
const handleSubmit = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();

if (!comment.trim()) return;
onSubmit(comment).then(() => setComment(''));
};
if (!comment.trim()) return;
onSubmit(comment).then(() => setComment(''));
};

return (
<Container>
<CommentInput value={comment} onChange={handleChange} placeholder="댓글 입력" rows={1} />
<SendButton type="submit" onClick={handleSubmit} disabled={disabled}>
<SendIcon />
</SendButton>
</Container>
);
}
return (
<Container isFocused={isFocused}>
<CommentInput
ref={ref}
value={comment}
onChange={handleChange}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
placeholder={`${writerName}님의 피드에 댓글을 남겨보세요!`}
rows={1}
/>
<SendButton type="submit" onClick={handleSubmit} disabled={disabled}>
{isFocused ? <SendFillIcon /> : <SendIcon />}
</SendButton>
</Container>
);
}
);

export default FeedCommentInput;

const Container = styled('form', {
background: '$gray800',
flexType: 'verticalCenter',
gap: '16px',
borderRadius: '10px',
variants: {
isFocused: {
true: {
outline: '1px solid $gray200',
},
false: {
outline: 'none',
},
},
},
});
const CommentInput = styled('textarea', {
minWidth: 0,
width: '692px',
height: '54px',
width: '100%',
height: '48px',
maxHeight: '120px',
padding: '14px 24px',
borderRadius: '25px',
background: '$gray700',
padding: '11px 16px',
borderRadius: '10px',
background: '$gray800',
color: '$gray10',
fontStyle: 'B2',
border: 'none',
Expand All @@ -57,12 +83,13 @@ const CommentInput = styled('textarea', {
color: '$gray300',
},
'@tablet': {
height: '48px',
padding: '12px 24px',
fontStyle: 'B3',
},
});
const SendButton = styled('button', {
width: '32px',
height: '32px',
width: '48px',
height: '48px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
});
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
import { styled } from 'stitches.config';
import CommentIcon from 'public/assets/svg/comment.svg';
import CommentHoverIcon from 'public/assets/svg/comment_hover.svg';
import LikeIcon from 'public/assets/svg/like.svg';
import LikeHoverIcon from 'public/assets/svg/like_hover.svg';
import LikeFillIcon from 'public/assets/svg/like_fill.svg';

interface FeedCommentLikeSectionProps {
isLiked: boolean;
commentCount: number;
likeCount: number;
onClickComment: () => void;
onClickLike: () => void;
}

export default function FeedCommentLikeSection({
isLiked,
commentCount,
likeCount,
onClickComment,
onClickLike,
}: FeedCommentLikeSectionProps) {
return (
<>
<CommentWrapper>
<CommentIcon />
<CommentWrapper onClick={onClickComment}>
<StyledCommentIcon />
<StyledCommentHoverIcon />
<span style={{ marginLeft: '4px' }}>댓글 {commentCount}</span>
</CommentWrapper>
<Divider />
<LikeWrapper onClick={onClickLike}>
{isLiked ? <LikeFillIcon /> : <LikeIcon />}
<LikeWrapper onClick={onClickLike} isLiked={isLiked}>
{isLiked ? (
<LikeFillIcon />
) : (
<>
<StyledLikeIcon />
<StyledLikeHoverIcon />
</>
)}
<Like isLiked={isLiked}>좋아요 {likeCount}</Like>
</LikeWrapper>
</>
Expand All @@ -36,20 +48,53 @@ const Divider = styled('div', {
width: '1px',
height: '24px',
});
const CommentWrapper = styled('div', {
const CommentWrapper = styled('button', {
width: '400px',
display: 'flex',
flexType: 'center',
color: '$gray400',
color: '$gray300',
fontStyle: 'T5',
'@tablet': {
width: '50%',
fontStyle: 'T6',
},
'&:hover svg:first-of-type': {
display: 'none',
},
'&:hover svg:last-of-type': {
display: 'block',
},
});
const StyledCommentIcon = styled(CommentIcon, {
display: 'block',
});
const StyledCommentHoverIcon = styled(CommentHoverIcon, {
display: 'none',
});
const LikeWrapper = styled(CommentWrapper, {
cursor: 'pointer',
userSelect: 'none',
variants: {
isLiked: {
true: {
'&:hover svg:first-of-type': {
display: 'block',
},
},
},
},
'&:hover svg:first-of-type': {
display: 'none',
},
'&:hover svg:nth-of-type(2)': {
display: 'block',
},
});
const StyledLikeIcon = styled(LikeIcon, {
display: 'block',
});
const StyledLikeHoverIcon = styled(LikeHoverIcon, {
display: 'none',
});
const Like = styled('span', {
marginLeft: '4px',
Expand Down
Loading

0 comments on commit 9509293

Please sign in to comment.