Skip to content

Commit 1cd183b

Browse files
committed
Implements PostReplies and PostCommentWrite forReplies props
1 parent 2c98427 commit 1cd183b

File tree

4 files changed

+124
-5
lines changed

4 files changed

+124
-5
lines changed

src/components/post/PostCommentsWrite.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,16 @@ export interface PostCommentsWriteProps {
3333
comment: string;
3434
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
3535
onWrite: () => void;
36+
forReplies?: boolean;
37+
onCancel?: () => void;
3638
}
3739

3840
const PostCommentsWrite: React.FC<PostCommentsWriteProps> = ({
3941
comment,
4042
onChange,
4143
onWrite,
44+
onCancel,
45+
forReplies,
4246
}) => {
4347
return (
4448
<PostCommentsWriteBlock>
@@ -48,7 +52,14 @@ const PostCommentsWrite: React.FC<PostCommentsWriteProps> = ({
4852
onChange={onChange}
4953
/>
5054
<div className="buttons-wrapper">
51-
<Button onClick={onWrite}>댓글 작성</Button>
55+
<Button inline onClick={onWrite}>
56+
댓글 작성
57+
</Button>
58+
{forReplies && (
59+
<Button onClick={onCancel} inline color="darkGray">
60+
취소
61+
</Button>
62+
)}
5263
</div>
5364
</PostCommentsWriteBlock>
5465
);

src/components/post/PostReplies.tsx

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,74 @@ import React from 'react';
22
import styled from 'styled-components';
33
import { Comment } from '../../lib/graphql/post';
44
import PostCommentsList from './PostCommentsList';
5+
import useBoolean from '../../lib/hooks/useBoolean';
6+
import palette from '../../lib/styles/palette';
7+
import PostCommentsWrite from './PostCommentsWrite';
58

69
const PostRepliesBlock = styled.div`
710
border: solid 1px rgba(0, 0, 0, 0.02);
811
background-color: rgba(0, 0, 0, 0.015);
9-
padding-left: 1.5rem;
10-
padding-right: 1.5rem;
12+
padding: 1.5rem;
1113
border-radius: 4px;
1214
margin-top: 1.3125rem;
1315
`;
1416

17+
const PullUp = styled.div`
18+
margin-top: -1.5rem;
19+
`;
20+
21+
const Separator = styled.div`
22+
width: 100%;
23+
height: 1px;
24+
background: ${palette.gray2};
25+
margin-bottom: 1.5rem;
26+
`;
27+
28+
const StartWritingButton = styled.button`
29+
cursor: pointer;
30+
height: 2.5rem;
31+
font-size: 1rem;
32+
border-radius: 4px;
33+
border: 1px solid ${palette.teal6};
34+
display: flex;
35+
outline: none;
36+
color: ${palette.teal6};
37+
width: 100%;
38+
align-items: center;
39+
justify-content: center;
40+
font-weight: 600;
41+
&:hover,
42+
&:focus {
43+
background: ${palette.teal6};
44+
color: white;
45+
}
46+
`;
47+
1548
export interface PostRepliesProps {
1649
comments: Comment[];
1750
}
1851

1952
const PostReplies: React.FC<PostRepliesProps> = ({ comments }) => {
53+
const [writing, onToggle] = useBoolean(false);
54+
const hasComments = comments.length > 0;
2055
return (
2156
<PostRepliesBlock>
57+
<PullUp />
2258
<PostCommentsList comments={comments} />
59+
{hasComments && <Separator />}
60+
{writing || !hasComments ? (
61+
<PostCommentsWrite
62+
comment=""
63+
onWrite={() => {}}
64+
onChange={() => {}}
65+
onCancel={onToggle}
66+
forReplies
67+
/>
68+
) : (
69+
<StartWritingButton onClick={onToggle}>
70+
답글 작성하기
71+
</StartWritingButton>
72+
)}
2373
</PostRepliesBlock>
2474
);
2575
};

src/components/post/__tests__/PostCommentsWrite.test.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ describe('PostCommentsWrite', () => {
2323
...utils,
2424
};
2525
};
26-
it('renders textarea and a button', () => {
27-
const { textarea, writeButton } = setup();
26+
it('renders textarea and a button, but not cancel button', () => {
27+
const { textarea, writeButton, queryByText } = setup();
2828
expect(textarea).toBeVisible();
2929
expect(writeButton).toBeVisible();
30+
const cancelButton = queryByText('취소');
31+
expect(cancelButton).toBeFalsy();
3032
});
3133
it('shows value on textarea', () => {
3234
const { textarea } = setup();
@@ -51,4 +53,14 @@ describe('PostCommentsWrite', () => {
5153

5254
expect(onWrite).toBeCalled();
5355
});
56+
it('shows cancel button when forReplies is true', () => {
57+
const { getByText } = setup({ forReplies: true });
58+
getByText('취소');
59+
});
60+
it('calls onCancel', () => {
61+
const onCancel = jest.fn();
62+
const { getByText } = setup({ forReplies: true, onCancel });
63+
fireEvent.click(getByText('취소'));
64+
expect(onCancel).toBeCalled();
65+
});
5466
});
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import * as React from 'react';
2+
import { render } from 'react-testing-library';
3+
import PostReplies, { PostRepliesProps } from '../PostReplies';
4+
5+
const sampleComments = [
6+
{
7+
id: '67139c27-cf3c-4da6-a25c-4b0ec54be379',
8+
user: {
9+
id: '0bcdf3e5-a228-42c3-8b52-3f0dc118dfd8',
10+
username: 'blablabla',
11+
profile: {
12+
thumbnail: null,
13+
},
14+
},
15+
text: 'ㅋㅋㅋ',
16+
replies_count: 2,
17+
created_at: '2019-06-19T14:56:26.022Z',
18+
},
19+
{
20+
id: '2f86fc23-2128-4e7c-99f5-f0fc4553afc8',
21+
user: {
22+
id: '0bcdf3e5-a228-42c3-8b52-3f0dc118dfd8',
23+
username: 'blablabla',
24+
profile: {
25+
thumbnail: null,
26+
},
27+
},
28+
text: 'sed',
29+
replies_count: 0,
30+
created_at: '2019-06-19T15:08:08.085Z',
31+
},
32+
];
33+
describe('PostReplies', () => {
34+
const setup = (props: Partial<PostRepliesProps> = {}) => {
35+
const initialProps: PostRepliesProps = {
36+
comments: sampleComments,
37+
};
38+
const utils = render(<PostReplies {...initialProps} {...props} />);
39+
return {
40+
...utils,
41+
};
42+
};
43+
it('renders properly', () => {
44+
setup();
45+
});
46+
});

0 commit comments

Comments
 (0)