Skip to content

Commit

Permalink
Merge pull request #377 from maetheartist/feat/HNG-#23-Create-and-imp…
Browse files Browse the repository at this point in the history
…lement-the-API-integration-of-the-comment-section-of-the-dynamic-blog-pages

Feat/hng #23 create and implement the api integration of the comment section of the dynamic blog pages
  • Loading branch information
mrcoded authored Jul 22, 2024
2 parents 5d0de25 + 6824ee3 commit 4140a6a
Show file tree
Hide file tree
Showing 5 changed files with 276 additions and 0 deletions.
50 changes: 50 additions & 0 deletions app/components/comment-section/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { FC } from "react";

import CommentSection from "./CommentSection";

interface Comment {
id: number;
author: string;
handle: string;
comment: string;
date: string;
}
const sampleComments: Comment[] = [
{
id: 1,
author: "Matthew",
handle: "@matt4real",
comment:
"Living a balanced lifestyle is essential. Focus on healthy eating, regular exercise, and mental well-being. A well-rounded lifestyle leads to a happier, more fulfilling life. Embrace positive habits and enjoy the journey.",
date: "21-Jun-2024 Wed 12:20pm",
},
{
id: 2,
author: "Abraham",
handle: "@SonofGod",
comment:
"Living a balanced lifestyle is essential. Focus on healthy eating, regular exercise, and mental well-being. A well-rounded lifestyle leads to a happier, more fulfilling life. Embrace positive habits and enjoy the journey.",
date: "21-Jun-2024 Wed 12:20pm",
},
{
id: 3,
author: "Salma Bee",
handle: "@msFits",
comment:
"Living a balanced lifestyle is essential. Focus on healthy eating, regular exercise, and mental well-being. A well-rounded lifestyle leads to a happier, more fulfilling life. Embrace positive habits and enjoy the journey.",
date: "21-Jun-2024 Wed 12:20pm",
},
];

const App: FC = () => {
const addComment = (newComment: Comment) => {
sampleComments.push(newComment);
};
return (
<div className="font-family('Inter')">
<CommentSection comments={sampleComments} onAddComment={addComment} />
</div>
);
};

export default App;
66 changes: 66 additions & 0 deletions app/components/comment-section/CommentSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { FC, useState } from "react";

import { Button } from "../../components/ui/button";
import Comments from "./Comments";

interface Comment {
id: number;
comment: string;
author: string;
handle: string;
date: string;
}

interface FooterCommentProperties {
comments: Comment[];
onAddComment: (comment: Comment) => void;
}

const CommentSection: FC<FooterCommentProperties> = ({
comments,
onAddComment,
}) => {
const [newCommentText, setNewCommentText] = useState<string>("");
const [author, setAuthor] = useState<string>("");
const [handle, setHandle] = useState<string>("");

const handleCommentChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setNewCommentText(event.target.value);
};

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const newComment: Comment = {
id: Date.now(),
comment: newCommentText,
author: author || "Anonymous",
handle: handle || "@unknown",
date: new Date().toLocaleString(),
};

onAddComment(newComment);
setNewCommentText("");
setAuthor("");
setHandle("");
};

return (
<div className="px-8 py-4">
<Comments comments={comments} />
<form onSubmit={handleSubmit} className="mt-4 flex flex-col gap-2">
<input
type="text"
value={newCommentText}
onChange={handleCommentChange}
placeholder="Write a comment..."
className="w-full rounded-md border p-4 md:w-3/6"
/>
<Button type="submit" className="w-1/6 bg-primary p-2 text-white">
Comment
</Button>
</form>
</div>
);
};

export default CommentSection;
78 changes: 78 additions & 0 deletions app/components/comment-section/Comments.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { FC } from "react";

import back from "../../../public/back.svg";
import commentIcon from "../../../public/comment.svg";
import userIcon from "../../../public/Ellipse 2.svg";
import notOk from "../../../public/notOk.svg";
import ok from "../../../public/ok.svg";
import share from "../../../public/share.svg";
import { Comment } from "./types";

interface FooterCommentProperties {
comments: Comment[];
}
const Comments: FC<FooterCommentProperties> = ({ comments }) => {
return (
<div className="lg:full w-full rounded border-2 border-solid bg-popover md:w-1/2">
<div className="px-2">
<h4 className="w-full self-stretch text-xl font-medium leading-normal">
Comments
</h4>
{comments.map((comment) => (
<div
key={comment.id}
className="flex-basis-0 my-4 flex flex-grow flex-col items-start rounded-md border-2 border-solid px-8 py-2"
>
<div className="bg-popover">
<div className="flex gap-1">
<img src={userIcon} alt="icon" />
<div className="text-sm md:text-xl lg:text-3xl">
<strong className="dark:text-neutral-1 md:text-xl lg:text-3xl">
{comment.author}
</strong>
<p className="my-0 text-sm font-medium leading-normal text-neutral-2 md:text-xl lg:text-3xl">
{comment.handle}
</p>
</div>
</div>
<p className="text-14 px-4 py-4 font-normal leading-normal text-muted-foreground md:text-xl lg:text-3xl">
{comment.comment}
</p>
<span className="text-[var(--neutral-1)]">{comment.date}</span>
<div className="inline-flex gap-3 md:text-xl lg:text-3xl">
<>
<img
src={ok}
alt="icon"
className="border-2 border-solid p-1"
/>
<img
src={notOk}
alt="icon"
className="border-2 border-solid p-1"
/>
</>
<img
src={share}
alt="icon"
className="border-2 border-solid p-1"
/>
<img
src={back}
alt="icon"
className="border-2 border-solid p-1"
/>
<img
src={commentIcon}
alt="icon"
className="border-2 border-solid p-1"
/>
</div>
</div>
</div>
))}
</div>
</div>
);
};
export default Comments;
66 changes: 66 additions & 0 deletions app/components/comment-section/Input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { FC, useState } from "react";

import { Button } from "../../components/ui/button";
import Comments from "./Comments";

interface Comment {
id: number;
comment: string;
author: string;
handle: string;
date: string;
}

interface FooterCommentProperties {
comments: Comment[];
onAddComment: (comment: Comment) => void;
}

const CommentSection: FC<FooterCommentProperties> = ({
comments,
onAddComment,
}) => {
const [newCommentText, setNewCommentText] = useState<string>("");
const [author, setAuthor] = useState<string>("");
const [handle, setHandle] = useState<string>("");

const handleCommentChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setNewCommentText(event.target.value);
};

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const newComment: Comment = {
id: Date.now(),
comment: newCommentText,
author: author || "Anonymous",
handle: handle || "@unknown",
date: new Date().toLocaleString(),
};

onAddComment(newComment);
setNewCommentText("");
setAuthor("");
setHandle("");
};

return (
<div>
<Comments comments={comments} />
<form onSubmit={handleSubmit} className="mt-4 flex w-3/4 flex-col gap-2">
<input
type="text"
value={newCommentText}
onChange={handleCommentChange}
placeholder="Write a comment..."
className="border border-[var(--primary)] p-2"
/>
<Button type="submit" className="by-primary p-2 text-white">
Comment
</Button>
</form>
</div>
);
};

export default CommentSection;
16 changes: 16 additions & 0 deletions app/components/comment-section/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export interface Comment {
id: number;
username?: string;
comment: string;
handle: string;
author?: string;
date?: string;
className?: string;
timestamp?: number;
image?: string;
}
export interface NewCommentInput {
name: string;
email: string;
text: string;
}

0 comments on commit 4140a6a

Please sign in to comment.