From 5fd4276bc74d24d5855e5960e4972cde5acc76a1 Mon Sep 17 00:00:00 2001
From: "DESKTOP-9FO96TP\\hehexd" <davidjakszta@outlook.de>
Date: Tue, 6 Jun 2023 05:12:04 +0200
Subject: [PATCH] added (post)comment button, comment api, actual name to Posts

---
 app/(content)/(home)/home/[postid]/page.tsx | 109 ++++++++++++++++++++
 app/(content)/(home)/home/page.tsx          |  59 +++--------
 app/api/comments/route.ts                   |  64 ++++++++++++
 components/comment-button.tsx               |  28 +++++
 components/like-button.tsx                  |  10 +-
 components/post-comment.tsx                 |  64 ++++++++++++
 components/post-item.tsx                    |  48 +++++++++
 7 files changed, 331 insertions(+), 51 deletions(-)
 create mode 100644 app/(content)/(home)/home/[postid]/page.tsx
 create mode 100644 app/api/comments/route.ts
 create mode 100644 components/comment-button.tsx
 create mode 100644 components/post-comment.tsx
 create mode 100644 components/post-item.tsx

diff --git a/app/(content)/(home)/home/[postid]/page.tsx b/app/(content)/(home)/home/[postid]/page.tsx
new file mode 100644
index 0000000..5345184
--- /dev/null
+++ b/app/(content)/(home)/home/[postid]/page.tsx
@@ -0,0 +1,109 @@
+import CommentButton from "@/components/comment-button";
+import LikeButton from "@/components/like-button";
+import PostCommentForm from "@/components/post-comment";
+import PostItem from "@/components/post-item";
+import { db } from "@/lib/db";
+import { Prisma } from "@prisma/client";
+/* export const revalidate = 5; */ // revalidate this page every 5 seconds
+
+
+
+type commentType = Prisma.CommentUncheckedCreateInput
+type messageType = any // Prisma.PostUncheckedCreateInput
+type messageItemProps = {
+    msg: messageType;
+};
+
+export default async function PostDetail({ params }: { params: { postid: string } }) {
+    const postid = params.postid
+    let comments = null
+    let message: messageType | null = null
+
+    try {
+        comments = await db.comment.findMany({
+            where: {
+                postId: postid
+            },
+            orderBy: {
+                createdAt: "desc"
+            },
+            include: {
+                user: true,
+            },
+        })
+
+        message = await db.post.findUnique({
+            where: {
+                id: postid
+            },
+            include: {
+                user: true,
+                Comment: true,
+            },
+        })
+
+    } catch (error) {
+        console.log("the database is not running, try: 'npx prisma migrate dev --name init' if you want to use the database")
+    }
+
+    return (
+        <div>
+            <h1>Post Section</h1>
+            <p>This will be where all comments show up.</p>
+            <p>Needs a reload after posting!!</p>
+            <PostItem msg={message} />
+
+            <PostCommentForm postid={postid} />
+
+            {comments ?
+                <>
+                    {comments.map((msg) => (
+                        <CommentItem msg={msg} key={msg.id} />
+                    ))}
+
+                </>
+                :
+                <p>no comments / no database</p>}
+        </div>
+    )
+}
+
+const CommentItem = ({ msg }: messageItemProps) => {
+    if (!msg.id) {
+        return <div></div>;
+    }
+    return (
+        <div className="flex border-b border-gray-200 py-4">
+            <div className="flex-shrink-0">
+                <div className="h-10 w-10 rounded-full bg-gray-300"></div> {/* Profile picture */}
+            </div>
+            <div className="ml-4 flex flex-col flex-grow">
+                <div>
+                    <div className="flex items-center">
+                        <span className="font-bold mr-2">{msg.user.name}</span>
+                        <span className="text-gray-500 text-sm">
+                            {formatDate(new Date(msg.createdAt!))}
+                        </span>
+                    </div>
+                    <div className="text-gray-800">{msg.message}</div>
+                </div>
+                <div className="mt-4 flex">
+                    <div className="bg-gray-200 rounded-lg py-10 px-20 mr-2">
+                        {/* potential Image */}
+                    </div>
+                </div>
+                <div className="flex justify-end" >
+                    <LikeButton data={msg} />
+                </div>
+            </div>
+        </div>
+    );
+};
+
+function formatDate(date: Date) {
+    return date.toLocaleDateString("en-US", {
+        day: "numeric",
+        month: "short",
+        year: "numeric"
+    });
+}
\ No newline at end of file
diff --git a/app/(content)/(home)/home/page.tsx b/app/(content)/(home)/home/page.tsx
index d50aa7c..862917b 100644
--- a/app/(content)/(home)/home/page.tsx
+++ b/app/(content)/(home)/home/page.tsx
@@ -1,10 +1,14 @@
+
+import CommentButton from "@/components/comment-button";
 import LikeButton from "@/components/like-button";
+import PostItem from "@/components/post-item";
+import MessageItem from "@/components/post-item";
 import PostMessageForm from "@/components/post-messages";
 import { db } from "@/lib/db";
 import { Prisma } from "@prisma/client";
 /* export const revalidate = 5; */ // revalidate this page every 60 seconds
 
-type messageType = Prisma.PostUncheckedCreateInput
+type messageType = any // Prisma.PostUncheckedCreateInput
 type messageItemProps = {
   msg: messageType;
 };
@@ -15,7 +19,11 @@ export default async function HomePage() {
     messages = await db.post.findMany({
       orderBy: {
         createdAt: "desc"
-      }
+      },
+      include: {
+        user: true,
+        Comment: true
+      },
     })
 
   } catch (error) {
@@ -25,13 +33,13 @@ export default async function HomePage() {
   return (
     <div>
       <h1>Home WIP</h1>
-      <p>This will be where all messages show up.</p>
+      <p>This will be where all Posts show up.</p>
       <p>Needs a reload after posting!!</p>
       <PostMessageForm data={messages} />
       {messages ?
         <>
           {messages.map((msg) => (
-            <MessageItem msg={msg} key={msg.id} />
+            <PostItem msg={msg} key={msg.id} />
           ))}
 
         </>
@@ -41,46 +49,3 @@ export default async function HomePage() {
   )
 }
 
-const MessageItem = ({ msg }: messageItemProps) => {
-  if (!msg.id) {
-    return <div></div>
-  }
-  return (
-    <div className="flex border-b border-gray-200 py-4">
-      <div className="flex-shrink-0">
-        <div className="h-10 w-10 rounded-full bg-gray-300"></div> {/* Profile picture */}
-      </div>
-      <div className="ml-4 flex flex-col">
-        <div>
-          <div className="flex items-center">
-            <span className="font-bold mr-2">{msg.userId}</span>
-            <span className="text-gray-500 text-sm">
-              {formatDate(new Date(msg.createdAt!))}
-            </span>
-          </div>
-          <div className="text-gray-800">{msg.content}</div>
-        </div>
-        <div className="mt-4">
-          <div className="flex items-center">
-            <div className="bg-gray-200 rounded-lg py-10 px-20 mr-2">
-              {/* potential Image */}
-            </div>
-          </div>
-        </div>
-        <LikeButton data={{
-          postId: msg.id,
-          userId: msg.userId
-        }} />
-        <span className="text-gray-600">Like Count: {msg.likeCount} | <span className="text-gray-600">ReplyButton (Number of Replies)</span></span>
-      </div>
-    </div>
-  );
-};
-
-function formatDate(date: Date) {
-  return date.toLocaleDateString("en-US", {
-    day: "numeric",
-    month: "short",
-    year: "numeric"
-  });
-}
\ No newline at end of file
diff --git a/app/api/comments/route.ts b/app/api/comments/route.ts
new file mode 100644
index 0000000..93429aa
--- /dev/null
+++ b/app/api/comments/route.ts
@@ -0,0 +1,64 @@
+import { authOptions } from "@/lib/auth";
+import { db } from "@/lib/db";
+import { Prisma } from "@prisma/client";
+import { getServerSession } from "next-auth/next";
+import { revalidatePath } from "next/cache";
+import { NextRequest, NextResponse } from "next/server";
+
+type comment = Prisma.CommentUncheckedCreateInput
+
+export async function POST(req: NextRequest) {
+    const session = await getServerSession(authOptions);
+
+    if (!session) {
+        return NextResponse.json({ status: 401 });
+    }
+
+    const userId = session.user.id
+    const data: comment = await req.json()
+
+    console.log("router data: " + data.message, "status:")
+
+    try {
+        await db.comment.create({
+            /* data: data */
+            data: {
+                message: data.message,
+                postId: data.postId,
+                userId: userId,
+            }
+        })
+        console.log("created")
+        const path = req.nextUrl.searchParams.get('path') || '/';
+        revalidatePath(path);
+
+        return NextResponse.json({ status: 201, message: 'Message Created' })
+
+    } catch (error: any) {
+        console.log("fail" + error);
+    }
+    console.log("post")
+}
+
+export async function GET(req: NextRequest, res: NextResponse) {
+    try {
+        const data = await req.json()
+        console.log("router data: " + data, "status:")
+    } catch (error) {
+
+    }
+
+    try {
+        const messages = await db.comment.findMany({
+            orderBy: {
+                createdAt: "desc"
+            }
+        })
+
+        return NextResponse.json({ status: 200, messages: messages })
+    } catch (error) {
+        console.log("fail" + error);
+        // res.status(400)
+    }
+    console.log("get")
+}
\ No newline at end of file
diff --git a/components/comment-button.tsx b/components/comment-button.tsx
new file mode 100644
index 0000000..a1c71ba
--- /dev/null
+++ b/components/comment-button.tsx
@@ -0,0 +1,28 @@
+"use client"
+
+import { Prisma } from "@prisma/client";
+import { useRouter } from "next/navigation";
+import { startTransition } from "react";
+import { Icons } from "./icons";
+import { Button } from "./ui/button";
+import Link from "next/link";
+
+type commentType = Prisma.CommentUncheckedCreateInput
+type postType = Prisma.PostSelect
+
+export default function CommentButton(props: { data: any }) {
+
+    const postid = props.data.id
+    const replyCount = props.data.Comment.length
+
+    return (
+        <div>
+            <Link href={`/home/${postid}`}>
+                <Button type="submit" variant="ghost" size="lg" className="float-right" >
+                    {replyCount}
+                    <Icons.messagecircle className="h-3 w-3" />
+                </Button>
+            </Link>
+        </div>
+    )
+}
\ No newline at end of file
diff --git a/components/like-button.tsx b/components/like-button.tsx
index 6a08934..1cbc47a 100644
--- a/components/like-button.tsx
+++ b/components/like-button.tsx
@@ -7,16 +7,17 @@ import { Icons } from "./icons";
 import { Button } from "./ui/button";
 
 type likeType = Prisma.LikeUncheckedCreateInput
+type postType = Prisma.PostUncheckedCreateInput
 
-export default function LikeButton(props: { data: likeType }) {
+export default function LikeButton(props: { data: any }) {
   const router = useRouter();
 
   async function postLike(e: any) {
     e.preventDefault()
-    const msgLikeData = props.data;
+    const postLikeData = props.data;
     const likeData = {} as likeType
-    likeData.userId = msgLikeData.userId
-    likeData.postId = msgLikeData.postId
+    likeData.userId = postLikeData.userId
+    likeData.postId = postLikeData.id!
 
     const response = await fetch('http://localhost:3000/api/likes', {
       method: 'PUT',
@@ -35,6 +36,7 @@ export default function LikeButton(props: { data: likeType }) {
     <div>
       <form onSubmit={postLike}>
         <Button type="submit" variant="ghost" size="lg" className="float-right" >
+          {props.data.likeCount}
           <Icons.heart className="h-3 w-3" />
         </Button>
       </form>
diff --git a/components/post-comment.tsx b/components/post-comment.tsx
new file mode 100644
index 0000000..6f80ff3
--- /dev/null
+++ b/components/post-comment.tsx
@@ -0,0 +1,64 @@
+"use client"
+
+import { Post, Prisma } from "@prisma/client";
+import { useRouter } from "next/navigation";
+import { startTransition, useEffect, useState } from "react";
+
+type commentType = Prisma.CommentUncheckedCreateInput
+
+export default function PostCommentForm(props: { postid: string }) {
+
+    const [formData, setFormData] = useState<commentType>({ message: "" } as commentType);
+    const router = useRouter();
+    const postid = props.postid
+
+    async function postComment(e: any) {
+        e.preventDefault()
+
+        formData.postId = postid;
+
+        const response = await fetch('http://localhost:3000/api/comments', {
+            method: 'POST',
+            body: JSON.stringify(formData)
+        })
+
+        startTransition(() => {
+            // Refresh the current route and fetch new data from the server without
+            // losing client-side browser or React state.
+            router.refresh();
+        });
+        return await response.json()
+    }
+
+    const characterCount = formData.message.length;
+    const isOverLimit = characterCount >= 1000;
+
+    const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
+        const { value } = e.target;
+        setFormData({ ...formData, message: value });
+    };
+
+    return (
+        <div className="p-4 pb-20">
+            <form onSubmit={postComment}>
+                <textarea
+                    placeholder="Write something..."
+                    name="message"
+                    value={formData.message}
+                    onChange={handleInputChange}
+                    className="w-full p-2 border border-gray-600 rounded-xl resize-none"
+                    rows={5}
+                    maxLength={1000}
+                ></textarea>
+                <div className="flex justify-end mt-2">
+                    <span className={`${isOverLimit ? "text-red-500" : "text-gray-500"} text-sm`}>
+                        {characterCount}/{1000}
+                    </span>
+                </div>
+                <button type="submit" className="mt-2 bg-gray-300 text-gray-800 px-4 py-2 rounded float-right">
+                    Post
+                </button>
+            </form>
+        </div>
+    )
+}
\ No newline at end of file
diff --git a/components/post-item.tsx b/components/post-item.tsx
new file mode 100644
index 0000000..f2cbce7
--- /dev/null
+++ b/components/post-item.tsx
@@ -0,0 +1,48 @@
+import CommentButton from "./comment-button";
+import LikeButton from "./like-button";
+
+type messageType = any // Prisma.PostUncheckedCreateInput
+type messageItemProps = {
+    msg: messageType;
+};
+
+export default function PostItem({ msg }: messageItemProps) {
+    if (!msg.id) {
+        return <div></div>;
+    }
+    return (
+        <div className="flex border-b border-gray-200 py-4">
+            <div className="flex-shrink-0">
+                <div className="h-10 w-10 rounded-full bg-gray-300"></div> {/* Profile picture */}
+            </div>
+            <div className="ml-4 flex flex-col flex-grow">
+                <div>
+                    <div className="flex items-center">
+                        <span className="font-bold mr-2">{msg.user.name}</span>
+                        <span className="text-gray-500 text-sm">
+                            {formatDate(new Date(msg.createdAt!))}
+                        </span>
+                    </div>
+                    <div className="text-gray-800">{msg.content}</div>
+                </div>
+                <div className="mt-4 flex">
+                    <div className="bg-gray-200 rounded-lg py-10 px-20 mr-2">
+                        {/* potential Image */}
+                    </div>
+                </div>
+                <div className="flex justify-end" >
+                    <LikeButton data={msg} />
+                    <CommentButton data={msg} />
+                </div>
+            </div>
+        </div>
+    )
+};
+
+function formatDate(date: Date) {
+    return date.toLocaleDateString("en-US", {
+        day: "numeric",
+        month: "short",
+        year: "numeric"
+    });
+}
\ No newline at end of file
-- 
GitLab