Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions amplify/backend/api/pinesearch/schema.graphql
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
type Comment {
author: String!
comment: String!
gpt_response: String!
}

type PostComments @model @auth(rules: [{allow: public}]) {
id: ID!
s3url: String!
users_comments: [Comment!]!
}

type PostLikes @model @auth(rules: [{allow: public}]) {
id: ID!
s3url: String
Expand Down
13 changes: 13 additions & 0 deletions public/icons/SendIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const SendIcon = () => {
return (
<svg width="30" height="30" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="ph:paper-plane-tilt-fill">
<path
id="Vector"
d="M21.6939 4.15687V4.17094L16.2376 22.1653C16.155 22.4576 15.985 22.7176 15.7504 22.9105C15.5158 23.1034 15.2278 23.2199 14.9251 23.2444C14.882 23.2481 14.8389 23.25 14.7957 23.25C14.512 23.2509 14.234 23.1706 13.9945 23.0186C13.7549 22.8666 13.5639 22.6492 13.4439 22.3922L10.0961 15.3244C10.063 15.2545 10.0524 15.176 10.0656 15.0998C10.0789 15.0236 10.1154 14.9534 10.1701 14.8988L15.5382 9.52969C15.673 9.38789 15.747 9.19908 15.7444 9.00351C15.7419 8.80794 15.6631 8.62108 15.5248 8.48278C15.3865 8.34448 15.1997 8.26567 15.0041 8.26317C14.8085 8.26067 14.6197 8.33466 14.4779 8.46937L9.10137 13.8375C9.04672 13.8922 8.97649 13.9287 8.90029 13.942C8.82409 13.9552 8.74566 13.9446 8.67574 13.9116L1.64449 10.5806C1.36835 10.4541 1.13595 10.2485 0.97674 9.98982C0.817528 9.73114 0.738657 9.43103 0.750116 9.1275C0.765386 8.81553 0.878328 8.51626 1.07297 8.27198C1.26762 8.02771 1.53412 7.85079 1.8348 7.76625L19.8292 2.31H19.8432C20.0994 2.23802 20.3702 2.2355 20.6277 2.30269C20.8852 2.36988 21.1202 2.50437 21.3085 2.69235C21.4969 2.88034 21.6319 3.11506 21.6996 3.37242C21.7673 3.62978 21.7653 3.90053 21.6939 4.15687Z"
fill="#1C3738"
/>
</g>
</svg>
);
};
2 changes: 1 addition & 1 deletion src/app/blog/[slug]/Buttons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const Buttons = ({ slug }: Props) => {
<LikeBtn slug={slug} />
<ShareBtn slug={slug} />
<AudioButton slug={slug} />
{/* <CommentsBtn /> */}
<CommentsBtn />
</div>
{/* <ChatPdfBtn /> */}
</div>
Expand Down
13 changes: 7 additions & 6 deletions src/app/blog/[slug]/buttons/CommentsBtn.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { useOpen } from "@/hooks/useOpen";
import { CommentIcon } from "../../../../../public/icons/CommentIcon";
import { ChatModal } from "../chatModal/ChatModal";

export const CommentsBtn = () => {
const { isOpen, containerRef, handleClose } = useOpen();

const scrollToComments = () => {
const commentsSection = document.getElementById("comments");
if (commentsSection) {
commentsSection.scrollIntoView({ behavior: "smooth" });
}
};
return (
<div>
<button
className="flex text-fig-gray bg-fig-grey-mint p-[10px] rounded-md mt-2 gap-1 hover:scale-110"
onClick={handleClose}
onClick={scrollToComments}
>
<CommentIcon /> <span className="font-medium">Comments</span>
</button>
{isOpen && <ChatModal containerRef={containerRef} handleClose={handleClose} />}
</div>
);
};
34 changes: 0 additions & 34 deletions src/app/blog/[slug]/chatModal/ChatForm.tsx

This file was deleted.

83 changes: 0 additions & 83 deletions src/app/blog/[slug]/chatModal/ChatModal.tsx

This file was deleted.

38 changes: 38 additions & 0 deletions src/app/blog/[slug]/comments/CommentForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { FormEvent, useRef, useState } from "react";
import { useAuth } from "@/hooks/useAuth";
import { SendIcon } from "../../../../../public/icons/SendIcon";

interface Props {
handleAddComment: (comment: string, author: string) => Promise<void>;
}
export const CommentForm = ({ handleAddComment }: Props) => {
const { getUser } = useAuth();
const user = getUser()?.attributes?.email;
const [commentValue, setCommentValue] = useState("");

const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
console.log(user);

if (!user) return;
if (!commentValue.trim()) return;

handleAddComment(commentValue, user);
setCommentValue("");
};

return (
<form className="mt-4 flex" onSubmit={handleSubmit}>
<input
className="bg-fig-ligth-mint rounded-xl border-2 border-fig-grey-mint p-4 text-base outline-none focus:shadow-md w-full text-gray-700"
type="text"
placeholder="Leave a commet"
value={commentValue}
onChange={(e) => setCommentValue(e.target.value)}
/>
<button className="translate-x-[-45px] hover:scale-125">
<SendIcon />
</button>
</form>
);
};
40 changes: 40 additions & 0 deletions src/app/blog/[slug]/comments/CommentItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
interface Props {
author: string;
comment: string;
gpt_response: string;
}

export const ChatItem = ({ author, comment, gpt_response }: Props) => {
return (
<div className="mt-10 space-y-2">
<div className="bg-fig-grey-mint p-4 rounded-md">
<Item author={author} comment={comment} />
</div>
<div className="bg-fig-ligth-mint ml-10 p-4 rounded-md">
<Item author={author} comment={gpt_response} isBot />
</div>
</div>
);
};

interface ItemProps {
author: string;
comment: string;
isBot?: boolean;
}

const Item = ({ author, comment, isBot }: ItemProps) => {
return (
<>
<div className="flex items-center justify-start gap-2">
<span className="h-6 w-6 flex justify-center items-center rounded-full bg-black text-white">
{isBot ? "P" : author[0].toUpperCase()}
</span>
<p className="font-bold">{isBot ? "Pinebot" : author}</p>
</div>
<div className="pl-8 pt-2">
<p>{comment}</p>
</div>
</>
);
};
89 changes: 89 additions & 0 deletions src/app/blog/[slug]/comments/Comments.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"use client";

import { useEffect, useState } from "react";
import { Comment, PostComments } from "@/models";
import { DataStore } from "aws-amplify";
import { ChatItem } from "./CommentItem";
import { CommentForm } from "./CommentForm";

interface Props {
slug: string;
}

export const Comments = ({ slug }: Props) => {
const [totalComments, setTotalComments] = useState<Comment[]>([]);
const [showTotalComments, setShowTotalComments] = useState(false);

const getComment = async () => {
const postComments: PostComments = (
await DataStore.query(PostComments, (postComments: any) => postComments.s3url.eq(slug))
)[0];

// if there are no comments is created --> test
if (!postComments?.id) {
await DataStore.save(
new PostComments({
s3url: slug,
users_comments: []
})
);
return;
}

setTotalComments(postComments.users_comments);
};

const updateRestComments = (postComent: PostComments): Comment[] => {
if (postComent.users_comments.length >= 10) return postComent.users_comments.slice(0, 9);

return postComent.users_comments;
};

const handleAddComment = async (comment: string, author: string) => {
const gptResponse = "Hi I'm Pinebot, glad you liked the post, thanks for reading us"; //await getGtp();

const currentComment = (
await DataStore.query(PostComments, (postLikes: any) => postLikes.s3url.eq(slug))
)[0]!;

const updatedPost = await DataStore.save(
PostComments.copyOf(currentComment, (updated) => {
updated.users_comments = [
{
author: author,
comment: comment,
gpt_response: gptResponse
},
...updateRestComments(updated)
];
})
);
setTotalComments(updatedPost.users_comments);
};

useEffect(() => {
getComment();
}, []);

return (
<div className="mt-2 pb-10" id="comments">
<h3 className="text-[27px] lg:text-3xl font-bold">Comments</h3>

<CommentForm handleAddComment={handleAddComment} />
{showTotalComments &&
totalComments.map((data, i) => <ChatItem key={data.author + i} {...data} />)}

{!showTotalComments &&
totalComments.slice(0, 1).map((data, i) => <ChatItem key={data.author + i} {...data} />)}

<div className="flex justify-center items-center">
<button
className=" font-bold text-lg underline text-fig-teal mt-10 cursor-pointer"
onClick={() => setShowTotalComments((prev) => !prev)}
>
{showTotalComments ? "Hide last 10 comments." : "Show the last 10 comments."}
</button>
</div>
</div>
);
};
10 changes: 7 additions & 3 deletions src/app/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { SortDirection, Storage, withSSRContext } from "aws-amplify";
import { MDXRemote } from "next-mdx-remote/rsc";
import { ImageClient } from "@/components/ImageClient";
import { Buttons } from "./Buttons";
import { Comments } from "./comments/Comments";

interface StaticParams {
slug: string;
Expand Down Expand Up @@ -60,8 +61,8 @@ export default async function blogPage({ params }: BlogPageParams) {

return (
mdxSource && (
<div className="py-4">
<section className="w-[90%] max-w-[806px] mx-auto">
<>
<section className="w-[90%] max-w-[806px] mx-auto py-4">
<ImageClient
className="w-full object-fills object-center h-[300px] rounded-md"
width={300}
Expand Down Expand Up @@ -104,7 +105,10 @@ export default async function blogPage({ params }: BlogPageParams) {
<MDXRemote source={mdxSource} />
</article>
</section>
</div>
<footer className="mt-5 w-[90%] max-w-[806px] mx-auto font-poping">
<Comments slug={params.slug} />
</footer>
</>
)
);
}
Loading