Skip to content

Commit cd4be95

Browse files
committed
feat: enhance CommentCreate and Comment components with reply functionality and user mentions
1 parent ab8f734 commit cd4be95

File tree

3 files changed

+87
-30
lines changed

3 files changed

+87
-30
lines changed

src/components/Comment/index.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ const Comment: React.FC<IComment> = ({
7777
</S.LikeButton>
7878

7979
<S.ReplyButton onClick={() => handleReply(listComment.id)}>
80-
Responder
80+
{replyComment?.isReplying && replyComment.id === listComment.id
81+
? "Cancelar resposta"
82+
: "Responder"}
8183
</S.ReplyButton>
8284
</S.ExtraInfo>
8385

@@ -86,7 +88,12 @@ const Comment: React.FC<IComment> = ({
8688
)}
8789

8890
{replyComment?.isReplying && replyComment.id === listComment.id && (
89-
<NewComment />
91+
<NewComment
92+
isReplying={true}
93+
replyId={listComment.id}
94+
replyUser={listComment.user.name}
95+
isReplyOverReply={isReplying}
96+
/>
9097
)}
9198
<S.ReplyContainer>{children}</S.ReplyContainer>
9299
</S.CommentInfos>

src/components/CommentCreate/index.tsx

Lines changed: 72 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,82 @@
1-
import React, { useState } from "react";
1+
import React, { useState, useMemo, useCallback, useEffect } from "react";
22
import * as S from "./styles";
33
import ViewMarkdown from "@components/ViewMarkdown";
44

5-
const CommentCreate = () => {
5+
export interface ICommentCreate {
6+
isReplying?: boolean;
7+
isReplyOverReply?: boolean;
8+
replyId?: number;
9+
replyUser?: string;
10+
}
11+
12+
const CommentCreate: React.FC<ICommentCreate> = ({
13+
isReplying = false,
14+
isReplyOverReply = false,
15+
replyId,
16+
replyUser,
17+
}) => {
618
const [comment, setComment] = useState("");
719
const [preview, setPreview] = useState<boolean>(false);
820

9-
const account = {
10-
isLogged: true,
11-
user: {
12-
userName: "Parlandim",
13-
avatar: "https://avatar.iran.liara.run/public/10",
14-
},
15-
};
21+
const account = useMemo(
22+
() => ({
23+
isLogged: true,
24+
user: {
25+
userName: "Parlandim",
26+
avatar: "https://avatar.iran.liara.run/public/10",
27+
},
28+
}),
29+
[]
30+
);
31+
32+
const clearComment = useCallback(() => {
33+
setComment("");
34+
}, []);
35+
36+
const withMention = useCallback(
37+
(content: string) => {
38+
if (!isReplyOverReply) {
39+
return content;
40+
}
41+
42+
if (content.includes(`@${replyUser}`)) {
43+
return content;
44+
}
1645

17-
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
18-
const { value } = e.target;
46+
return `@${replyUser}\n${content}`;
47+
},
48+
[isReplying, replyUser, isReplyOverReply]
49+
);
1950

20-
const replaceString = value.replace(/\n\n/g, "\n<br>");
51+
const handleChange = useCallback(
52+
(e: React.ChangeEvent<HTMLTextAreaElement>) => {
53+
const { value } = e.target;
54+
const replaceString = value.replace(/\n\n/g, "\n<br>");
55+
setComment(withMention(replaceString));
56+
},
57+
[withMention]
58+
);
2159

22-
setComment(replaceString);
23-
};
60+
const handlePreview = useCallback(() => {
61+
setPreview((prev) => !prev);
62+
}, []);
2463

25-
const handlePreview = () => {
26-
setPreview(!preview);
27-
};
64+
const userSection = useMemo(
65+
() => (
66+
<S.UserSection>
67+
<S.UserInfos>
68+
{account.isLogged && (
69+
<>
70+
<S.Avatar src={account.user.avatar} />
71+
<S.UserName>{account.user.userName}</S.UserName>
72+
</>
73+
)}
74+
</S.UserInfos>
75+
<S.Button>{account.isLogged ? "comentar" : "fazer login"}</S.Button>
76+
</S.UserSection>
77+
),
78+
[account]
79+
);
2880

2981
return (
3082
<S.Container>
@@ -33,6 +85,8 @@ const CommentCreate = () => {
3385
<S.Button onClick={handlePreview}>
3486
{preview ? "Escrever" : "Pré visualizar"}
3587
</S.Button>
88+
89+
{isReplying && <S.ReplyText>Respondendo a @{replyUser}</S.ReplyText>}
3690
</S.ButtonsWrapper>
3791

3892
{!preview && (
@@ -49,17 +103,7 @@ const CommentCreate = () => {
49103
</S.Preview>
50104
)}
51105

52-
<S.UserSection>
53-
<S.UserInfos>
54-
{account.isLogged && (
55-
<>
56-
<S.Avatar src={account.user.avatar} />
57-
<S.UserName>{account.user.userName}</S.UserName>
58-
</>
59-
)}
60-
</S.UserInfos>
61-
<S.Button>{account.isLogged ? "comentar" : "fazer login"}</S.Button>
62-
</S.UserSection>
106+
{userSection}
63107
</S.CommentSection>
64108
</S.Container>
65109
);

src/components/CommentCreate/styles.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ export const Button = styled.button`
3535
font-size: 0.8rem;
3636
`;
3737

38+
export const ReplyText = styled.span`
39+
color: ${(props) => props.theme.colors.secondary};
40+
font-size: 0.8rem;
41+
margin-left: 10px;
42+
`;
43+
3844
export const CommentInput = styled.textarea`
3945
width: 100%;
4046
border: none;

0 commit comments

Comments
 (0)