Skip to content
This repository was archived by the owner on Dec 12, 2024. It is now read-only.

Commit fa69ebc

Browse files
authored
Merge pull request #9 from Jaagrav/main
Added Feature(s): Replies to comments
2 parents 5f4f338 + 7379b79 commit fa69ebc

File tree

5 files changed

+8944
-32
lines changed

5 files changed

+8944
-32
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ Code House comes up with a whole bunch of amazing features to provide you the be
7878
- 🔺 **Upvote/Comment on Cheatsheets**
7979
- 📬 **Newsletter** (once a week)
8080
- 💻 **Fully Responsive**
81+
- 🔤 **Reply to a comment**
8182

8283
Code House is the next revolutionary app to hunt the best cheat sheets for all types ✨️
8384

@@ -157,7 +158,6 @@ Here are some idea that is coming really soon 👀
157158

158159
- Profile Page
159160
- PWA, **In Progress ⏳️**
160-
- Reply to a comment
161161
- Markdown support for feature requests
162162
- Twitter and Facebook Auth, **In Progress ⏳️**
163163
- Perform Operations with API

components/core/InfoBar.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@ const InfoBar = ({
251251
}
252252
};
253253

254+
console.log(comments);
255+
254256
return (
255257
<div className="w-full lg:w-[65%] xl:w-[65%] h-full min-h-[90vh] bg-white rounded-md white-light-shadow border border-[#ddd] p-7 dark:bg-[#1F1F1F] dark:border-[#555] dark:text-white">
256258
{loading ? (
@@ -373,8 +375,8 @@ const InfoBar = ({
373375
</div>
374376

375377
{comments &&
376-
comments.map((comment, key) => (
377-
<Comment key={key} comment={comment} />
378+
comments.map((comment, index) => (
379+
<Comment key={index} id={id} index={index} user={user} comments={comments} comment={comment} review={review} fetchAgain={fetchAgain} setFetchAgain={setFetchAgain} setOpen={setOpen}/>
378380
))}
379381
</>
380382
)}

components/utils/Comment.js

+29-20
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,43 @@
1-
import React from "react";
1+
import React, {useState} from "react";
2+
import {ReplyButton, Replies, ReplyBox} from "./ReplyComment";
23

34
// formating time
45
// we get time in milliseconds
56
// https://www.epochconverter.com/
67
import { formatRelative } from "date-fns";
78

8-
const Comment = ({ comment }) => {
9+
const Comment = ({ id, user, comments, comment, review, index, fetchAgain, setFetchAgain, setOpen }) => {
10+
const [toggleReplyBox, setToggleReplyBox] = useState(false),
11+
[toggleReplies, setToggleReplies] = useState(true);
12+
913
return (
1014
<div
11-
className="rounded-md border border-[#ccc] dark:bg-[#2f2f2f] dark:border-[#555] p-2 flex items-center hover:bg-white duration-200 mt-2"
15+
className="rounded-md border border-[#ccc] dark:bg-[#2f2f2f] dark:border-[#555] hover:bg-white p-2 mt-2"
1216
data-aos="fade-left"
1317
>
14-
<img
15-
src={
16-
comment.photoURL
17-
? comment.photoURL
18-
: `https://unavatar.vercel.app/${comment.email}`
19-
}
20-
alt={comment.email}
21-
className="h-[50px] w-[50px] rounded-md pixelated white-light-shadow"
22-
/>
23-
<div className="ml-2">
24-
<h2 className="font-semibold text-base text-[#222] dark:text-[#fafafa]">
25-
{comment.comment}
26-
</h2>
27-
<h4 className="text-xs font-semibold text-[#666] capitalize dark:text-[#aaa]">
28-
{formatRelative(comment.time, new Date())}{" "}
29-
{comment.name && comment.name}
30-
</h4>
18+
<div className="flex items-center duration-200">
19+
<img
20+
src={
21+
comment.photoURL
22+
? comment.photoURL
23+
: `https://unavatar.vercel.app/${comment.email}`
24+
}
25+
alt={comment.email}
26+
className="h-[50px] w-[50px] rounded-md pixelated white-light-shadow"
27+
/>
28+
<div className="ml-2">
29+
<h2 className="font-semibold text-base text-[#222] dark:text-[#fafafa]">
30+
{comment.comment}
31+
</h2>
32+
<h4 className="text-xs font-semibold text-[#666] capitalize dark:text-[#aaa]">
33+
{formatRelative(comment.time, new Date())}{" "}
34+
{comment.name && comment.name}
35+
{user.email && <>{" • "}<ReplyButton toggleReplyBox={toggleReplyBox} setToggleReplyBox={setToggleReplyBox} /></>}
36+
</h4>
37+
</div>
3138
</div>
39+
{comment?.replies && <Replies toggleReplies={toggleReplies} setToggleReplies={setToggleReplies} replies={comment.replies} />}
40+
<ReplyBox id={id} toggleReplyBox={toggleReplyBox} user={user} comments={comments} comment={comment} review={review} index={index} fetchAgain={fetchAgain} setFetchAgain={setFetchAgain} setOpen={setOpen} />
3241
</div>
3342
);
3443
};

components/utils/ReplyComment.js

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import React from 'react';
2+
import { formatRelative } from "date-fns";
3+
import {
4+
FiSend,
5+
} from "react-icons/fi";
6+
7+
function Reply(props) {
8+
const {email, name, photoURL, reply, time} = props.reply;
9+
return (
10+
<div className="flex items-center duration-200 mt-2">
11+
<img
12+
src={
13+
photoURL
14+
? photoURL
15+
: `https://unavatar.vercel.app/${email}`
16+
}
17+
alt={email}
18+
className="h-[30px] w-[30px] rounded-md pixelated white-light-shadow"
19+
/>
20+
<div className="ml-2">
21+
<h2 className="font-semibold text-xs text-[#222] dark:text-[#fafafa]">
22+
{reply}
23+
</h2>
24+
<h4 className="text-xs font-semibold text-[#666] capitalize dark:text-[#aaa]">
25+
{formatRelative(time, new Date())}{" "}
26+
{name && name}
27+
</h4>
28+
</div>
29+
</div>
30+
)
31+
}
32+
33+
function Replies({toggleReplies, setToggleReplies, replies}) {
34+
return (
35+
<div className="rounded-md border border-[#ccc] dark:bg-[#2f2f2f] dark:border-[#555] hover:bg-white p-2 mt-2">
36+
<div className="flex items-center justify-between w-full">
37+
<h1 className="font-semibold text-sm lg:text-base xl:text-lg text-[#555] dark:text-[#ccc]">
38+
Replies ({replies && replies.length})
39+
</h1>
40+
<span className="text-xs text-[#3d5eff] font-semibold continuous-line cursor-pointer" onClick={() => setToggleReplies(!toggleReplies)}>
41+
{!toggleReplies && <>Show</>}
42+
{toggleReplies && <>Hide</>}
43+
</span>
44+
</div>
45+
{toggleReplies && replies.map((reply, index) => (
46+
<Reply key={`reply-${index}`} reply={reply} />
47+
))}
48+
</div>
49+
)
50+
}
51+
52+
function ReplyButton({toggleReplyBox, setToggleReplyBox}) {
53+
return (
54+
<span className="text-xs text-[#3d5eff] font-semibold continuous-line cursor-pointer" onClick={() => setToggleReplyBox(!toggleReplyBox)}>
55+
{toggleReplyBox && <>Close Reply</>}
56+
{!toggleReplyBox && <>Reply</>}
57+
</span>
58+
)
59+
}
60+
61+
function ReplyBox({id, toggleReplyBox, user, comments, comment, review, index, fetchAgain, setFetchAgain, setOpen}) {
62+
const [reply, setReply] = React.useState('');
63+
const sendReply = () => {
64+
const url = `/api/POST/${review ? `comment-review-cheatsheet` : `comment-cheatsheet`}`;
65+
if(user?.email){
66+
if(reply.trim()) {
67+
const temp = [...comments];
68+
temp[index].replies = comments[index].replies ? [...comments[index].replies] : [];
69+
temp[index].replies.unshift({
70+
name: user.displayName ? user.displayName : "",
71+
photoURL: user.photoURL ? user.photoURL : "",
72+
reply: reply,
73+
email: user.email,
74+
time: new Date().getTime(),
75+
});
76+
fetch(url, {
77+
method: "POST",
78+
body: JSON.stringify({
79+
id: id,
80+
comments: [...temp],
81+
}),
82+
});
83+
84+
setFetchAgain(fetchAgain + 1);
85+
setReply('');
86+
}
87+
} else setOpen(true);
88+
}
89+
return (
90+
<>
91+
{toggleReplyBox && <div className="reply-box">
92+
<div className="flex items-center justify-between rounded-md border border-[#3d5eff] dark:bg-[#1F1F1F] mt-2 p-1">
93+
<input
94+
type="text"
95+
value={reply}
96+
onChange={e => setReply(e.target.value)}
97+
placeholder={`Replying to ${comment.name}...`}
98+
className="h-full py-1 pl-2 w-full bg-transparent"
99+
onKeyDown={e => {if(e.keyCode === 13) {sendReply()}}}
100+
/>
101+
<div
102+
className="bg-[#3d5eff] p-3 pr-4 cursor-pointer shine rounded-lg"
103+
onClick={sendReply}
104+
>
105+
<FiSend
106+
className="text-white"
107+
style={{ transform: "rotate(45deg)" }}
108+
/>
109+
</div>
110+
</div>
111+
</div>}
112+
</>
113+
)
114+
}
115+
116+
export {Reply, Replies, ReplyButton, ReplyBox};

0 commit comments

Comments
 (0)