From fc05dd1a64fb933a5c97338b6ac13390dbaa64d8 Mon Sep 17 00:00:00 2001
From: "Kartikey S. Chauhan" <skartikey314@gmail.com>
Date: Sun, 2 Jun 2024 20:58:06 +0530
Subject: [PATCH 1/8] feat: add option to delete posts from web UI

---
 components/post.js           | 29 +++++++++++++++++++++++++++++
 components/posts.js          |  1 +
 pages/api/web/post/delete.js | 25 +++++++++++++++++++++++++
 public/posts.css             | 25 +++++++++++++++++++++++++
 4 files changed, 80 insertions(+)
 create mode 100644 pages/api/web/post/delete.js

diff --git a/components/post.js b/components/post.js
index 3b93d4ff..c2b95494 100644
--- a/components/post.js
+++ b/components/post.js
@@ -7,6 +7,7 @@ import Content from './content'
 import Video from './video'
 import Image from 'next/image'
 import Reaction from './reaction'
+import { useState } from 'react'
 import EmojiPicker from 'emoji-picker-react'
 
 const imageFileTypes = ['jpg', 'jpeg', 'png', 'gif', 'webp']
@@ -28,6 +29,7 @@ const Post = ({
   profile = false,
   user = {
     username: 'abc',
+    id: 'abc',
     avatar: '',
     displayStreak: false,
     streakCount: 0
@@ -44,6 +46,30 @@ const Post = ({
   swrKey,
   authSession
 }) => {
+  const [isVisible, setIsVisible] = useState(true);
+  
+  const deletePost = async (id) => {
+    try {
+      const response = await fetch('/api/web/post/delete', {
+        method: 'DELETE',
+        headers: {
+          'Content-Type': 'application/json',
+        },
+        body: JSON.stringify({ id }) 
+      });
+      const responseText = await response.text()
+      if (responseText.includes("Post Deleted")){
+        setIsVisible(false);
+      }
+    } catch (error) {
+      console.error('Error:', error);
+    }
+  };
+
+  if (!isVisible) {
+    return null; 
+  }
+
   return (
     <>
       <section
@@ -154,6 +180,7 @@ const Post = ({
           </div>
         )}
         <footer className="post-reactions" aria-label="Emoji reactions">
+        <div style={{ display: 'flex', flexWrap: 'wrap', flexGrow: 1 }}>
           {reactions.map(reaction => (
             <Reaction
               key={id + reaction.name}
@@ -169,6 +196,8 @@ const Post = ({
               +
             </div>
           )}
+          </div>
+          <Icon glyph="delete" size={32} className="delete-button post-reaction" onClick={() => deletePost(id)} />
         </footer>
       </section>
     </>
diff --git a/components/posts.js b/components/posts.js
index a0d98e02..5265c75a 100644
--- a/components/posts.js
+++ b/components/posts.js
@@ -70,6 +70,7 @@ const Posts = ({ posts = [], swrKey = null }) => {
         {posts.map(post => (
           <Post
             key={post.id}
+            userID={post.user.id}
             openEmojiPicker={openEmojiPicker}
             authStatus={status}
             authSession={session}
diff --git a/pages/api/web/post/delete.js b/pages/api/web/post/delete.js
new file mode 100644
index 00000000..4d747674
--- /dev/null
+++ b/pages/api/web/post/delete.js
@@ -0,0 +1,25 @@
+import { getServerSession } from 'next-auth/next';
+import { authOptions } from '../../auth/[...nextauth]';
+import prisma from '../../../../lib/prisma';
+
+export default async (req, res) => {
+  const session = await getServerSession(req, res, authOptions);
+
+  if (!session?.user) {
+    console.log('Unauthorized access attempt');
+    return res.status(401).send({message: "Unauthorized"});
+  }
+
+  try {
+    const update = await prisma.updates.delete({
+      where: { id: req.body.id },
+    });
+
+    console.log('API Response:', update);
+
+    return res.status(200).send({message: "Post Deleted"});
+  } catch (e) {
+    console.error('Error deleting post:', e);
+    return res.status(500).json({ error: true, message: 'Internal Server Error' });
+  }
+};
diff --git a/public/posts.css b/public/posts.css
index dedca7a4..2bf64dc2 100644
--- a/public/posts.css
+++ b/public/posts.css
@@ -24,6 +24,7 @@
   text-decoration: none;
   display: flex;
   align-items: center;
+  justify-content: space-between;
   margin-bottom: 8px;
   line-height: 1;
 }
@@ -40,6 +41,7 @@
 
 .post-header-container {
   padding-left: 8px;
+  flex-grow: 1;
 }
 
 .post-header-name {
@@ -122,6 +124,7 @@ a.post-text-mention {
   align-items: center;
   margin-top: 16px;
 }
+
 .post-attachment {
   border-radius: 6px;
   overflow: hidden;
@@ -160,6 +163,7 @@ a.post-attachment:first-child:last-child {
   flex-wrap: wrap;
   margin-top: 16px;
   margin-bottom: -12px;
+  justify-content: space-between;
 }
 
 .post-reaction {
@@ -198,3 +202,24 @@ a.post-attachment:first-child:last-child {
   width: 24px;
   height: 24px;
 }
+
+.delete-button {
+  color: var(--colors-background);
+  background-color: #ec3750;
+  border-color: black;
+}
+
+.delete-button:hover {
+  transform: scale(1.2);
+  color: var(--colors-background);
+  animation: wiggle 0.5s ease-in-out infinite;
+}
+
+@keyframes wiggle {
+  0%, 100% {
+    transform: rotate(-5deg) scale(1.2);
+  }
+  50% {
+    transform: rotate(5deg) scale(1.2);
+  }
+}

From 99a53515c4555ae6d2ad5153e3e560acbfd6ff78 Mon Sep 17 00:00:00 2001
From: "Kartikey S. Chauhan" <skartikey314@gmail.com>
Date: Mon, 3 Jun 2024 15:48:55 +0530
Subject: [PATCH 2/8] fix: button only appears if authenticated user is the
 owner of the post

---
 components/post.js           | 85 ++++++++++++++++++++++++------------
 pages/api/web/session/get.js | 31 +++++++++++++
 2 files changed, 88 insertions(+), 28 deletions(-)
 create mode 100644 pages/api/web/session/get.js

diff --git a/components/post.js b/components/post.js
index c2b95494..724ff69e 100644
--- a/components/post.js
+++ b/components/post.js
@@ -7,7 +7,7 @@ import Content from './content'
 import Video from './video'
 import Image from 'next/image'
 import Reaction from './reaction'
-import { useState } from 'react'
+import { useState, useEffect } from 'react'
 import EmojiPicker from 'emoji-picker-react'
 
 const imageFileTypes = ['jpg', 'jpeg', 'png', 'gif', 'webp']
@@ -34,6 +34,7 @@ const Post = ({
     displayStreak: false,
     streakCount: 0
   },
+  sessionID = 'abc',
   text,
   attachments = [],
   mux = [],
@@ -41,13 +42,25 @@ const Post = ({
   postedAt,
   slackUrl,
   muted = false,
-  openEmojiPicker = () => {},
+  openEmojiPicker = () => { },
   authStatus,
   swrKey,
   authSession
 }) => {
   const [isVisible, setIsVisible] = useState(true);
-  
+  const [sessionUserId, setSessionUserId] = useState(null);
+
+  useEffect(() => {
+    if (authStatus === 'authenticated') {
+        const fetchSessionUserID = async () => {
+            const id = await getSessionUserID(user.id);
+            setSessionUserId(id);
+        };
+        fetchSessionUserID();
+    }
+}, [user.id, authStatus]);
+
+
   const deletePost = async (id) => {
     try {
       const response = await fetch('/api/web/post/delete', {
@@ -55,10 +68,10 @@ const Post = ({
         headers: {
           'Content-Type': 'application/json',
         },
-        body: JSON.stringify({ id }) 
+        body: JSON.stringify({ id })
       });
       const responseText = await response.text()
-      if (responseText.includes("Post Deleted")){
+      if (responseText.includes("Post Deleted")) {
         setIsVisible(false);
       }
     } catch (error) {
@@ -67,7 +80,7 @@ const Post = ({
   };
 
   if (!isVisible) {
-    return null; 
+    return null;
   }
 
   return (
@@ -106,11 +119,10 @@ const Post = ({
                 <span className="post-header-name">
                   <strong>@{user.username}</strong>
                   <span
-                    className={`badge post-header-streak ${
-                      !user.displayStreak || user.streakCount === 0
-                        ? 'header-streak-zero'
-                        : ''
-                    }`}
+                    className={`badge post-header-streak ${!user.displayStreak || user.streakCount === 0
+                      ? 'header-streak-zero'
+                      : ''
+                      }`}
                     title={`${user.streakCount}-day streak`}
                   >
                     {`${user.streakCount <= 7 ? user.streakCount : '7+'}`}
@@ -180,24 +192,24 @@ const Post = ({
           </div>
         )}
         <footer className="post-reactions" aria-label="Emoji reactions">
-        <div style={{ display: 'flex', flexWrap: 'wrap', flexGrow: 1 }}>
-          {reactions.map(reaction => (
-            <Reaction
-              key={id + reaction.name}
-              {...reaction}
-              postID={id}
-              authStatus={authStatus}
-              authSession={authSession}
-              swrKey={swrKey}
-            />
-          ))}
-          {authStatus == 'authenticated' && (
-            <div className="post-reaction" onClick={() => openEmojiPicker(id)}>
-              +
-            </div>
-          )}
+          <div style={{ display: 'flex', flexWrap: 'wrap', flexGrow: 1 }}>
+            {reactions.map(reaction => (
+              <Reaction
+                key={id + reaction.name}
+                {...reaction}
+                postID={id}
+                authStatus={authStatus}
+                authSession={authSession}
+                swrKey={swrKey}
+              />
+            ))}
+            {authStatus == 'authenticated' && (
+              <div className="post-reaction" onClick={() => openEmojiPicker(id)}>
+                +
+              </div>
+            )}
           </div>
-          <Icon glyph="delete" size={32} className="delete-button post-reaction" onClick={() => deletePost(id)} />
+          {( authStatus == 'authenticated' && sessionUserId === user.id) && <Icon glyph="delete" size={32} className="delete-button post-reaction" onClick={() => deletePost(id)} />}
         </footer>
       </section>
     </>
@@ -205,3 +217,20 @@ const Post = ({
 }
 
 export default Post
+
+const getSessionUserID = async (id) => {
+  try {
+    const response = await fetch('/api/web/session/get', {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify({ id })
+    });
+
+    const responseText = JSON.parse(await response.text());
+    return responseText.message;
+  } catch (error) {
+    console.error('Error:', error);
+  }
+}
\ No newline at end of file
diff --git a/pages/api/web/session/get.js b/pages/api/web/session/get.js
new file mode 100644
index 00000000..0b20b052
--- /dev/null
+++ b/pages/api/web/session/get.js
@@ -0,0 +1,31 @@
+import { getServerSession } from 'next-auth/next';
+import { authOptions } from '../../auth/[...nextauth]';
+import prisma from '../../../../lib/prisma';
+
+export default async (req, res) => {
+    const session = await getServerSession(req, res, authOptions);
+
+    if (!session?.user) {
+        console.log('Unauthorized access attempt');
+        return res.status(401).send({ message: "Unauthorized" });
+    }
+
+    try {
+        const update = await prisma.session.findFirst({
+            where: {
+                userId: req.body.id
+            },
+            orderBy: {
+                expires: 'desc'
+            }
+        });
+        if (update) {
+            const userId = update.userId;
+            return res.status(200).send({ message: userId });
+        }
+        return res.status(200).send({ message: false });
+    } catch (e) {
+        console.error('Error deleting post:', e);
+        return res.status(500).json({ error: true, message: 'Internal Server Error' });
+    }
+};

From 882b15e9ebb4187a4a73eeeb517c1a781565d46b Mon Sep 17 00:00:00 2001
From: "Kartikey S. Chauhan" <skartikey314@gmail.com>
Date: Mon, 3 Jun 2024 20:22:07 +0530
Subject: [PATCH 3/8] Resolve comments

---
 components/post.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/post.js b/components/post.js
index 724ff69e..6e5546c0 100644
--- a/components/post.js
+++ b/components/post.js
@@ -228,7 +228,7 @@ const getSessionUserID = async (id) => {
       body: JSON.stringify({ id })
     });
 
-    const responseText = JSON.parse(await response.text());
+    const responseText = await response.json();
     return responseText.message;
   } catch (error) {
     console.error('Error:', error);

From 9b5e057b9ee8f38672821de3d8c92134cf64dbbd Mon Sep 17 00:00:00 2001
From: "Kartikey S. Chauhan" <skartikey314@gmail.com>
Date: Thu, 13 Jun 2024 08:02:32 +0530
Subject: [PATCH 4/8] Adds toast!

---
 components/post.js | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/components/post.js b/components/post.js
index 6e5546c0..380b63a4 100644
--- a/components/post.js
+++ b/components/post.js
@@ -8,6 +8,7 @@ import Video from './video'
 import Image from 'next/image'
 import Reaction from './reaction'
 import { useState, useEffect } from 'react'
+import toast from 'react-hot-toast'
 import EmojiPicker from 'emoji-picker-react'
 
 const imageFileTypes = ['jpg', 'jpeg', 'png', 'gif', 'webp']
@@ -62,21 +63,24 @@ const Post = ({
 
 
   const deletePost = async (id) => {
-    try {
-      const response = await fetch('/api/web/post/delete', {
+    toast.promise(
+      fetch('/api/web/post/delete', {
         method: 'DELETE',
         headers: {
           'Content-Type': 'application/json',
         },
         body: JSON.stringify({ id })
-      });
-      const responseText = await response.text()
-      if (responseText.includes("Post Deleted")) {
-        setIsVisible(false);
+      }).then(response => response.text()).then(responseText => {
+        if (responseText.includes("Post Deleted")) {
+          setIsVisible(false);
+        }
+      }),
+      {
+        loading: 'Deleting post...',
+        success: 'Post Deleted Successfully!',
+        error: 'Error deleting post.',
       }
-    } catch (error) {
-      console.error('Error:', error);
-    }
+    );
   };
 
   if (!isVisible) {

From e0eed1658f2e8e49e045df02c8248ceeaaa94e6e Mon Sep 17 00:00:00 2001
From: JosiasAurel <ndjosiasaurel@gmail.com>
Date: Sat, 31 Aug 2024 05:53:14 +0100
Subject: [PATCH 5/8] use auth session passed down from parent component into
 post

---
 components/post.js | 16 +---------------
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/components/post.js b/components/post.js
index 380b63a4..33db1046 100644
--- a/components/post.js
+++ b/components/post.js
@@ -1,5 +1,4 @@
 import { convertTimestampToDate } from '../lib/dates'
-import { proxy } from '../lib/images'
 import { filter } from 'lodash'
 import Icon from '@hackclub/icons'
 import Link from 'next/link'
@@ -9,7 +8,6 @@ import Image from 'next/image'
 import Reaction from './reaction'
 import { useState, useEffect } from 'react'
 import toast from 'react-hot-toast'
-import EmojiPicker from 'emoji-picker-react'
 
 const imageFileTypes = ['jpg', 'jpeg', 'png', 'gif', 'webp']
 
@@ -49,18 +47,6 @@ const Post = ({
   authSession
 }) => {
   const [isVisible, setIsVisible] = useState(true);
-  const [sessionUserId, setSessionUserId] = useState(null);
-
-  useEffect(() => {
-    if (authStatus === 'authenticated') {
-        const fetchSessionUserID = async () => {
-            const id = await getSessionUserID(user.id);
-            setSessionUserId(id);
-        };
-        fetchSessionUserID();
-    }
-}, [user.id, authStatus]);
-
 
   const deletePost = async (id) => {
     toast.promise(
@@ -213,7 +199,7 @@ const Post = ({
               </div>
             )}
           </div>
-          {( authStatus == 'authenticated' && sessionUserId === user.id) && <Icon glyph="delete" size={32} className="delete-button post-reaction" onClick={() => deletePost(id)} />}
+          {( authStatus == 'authenticated' && authSession.user.id === user.id) && <Icon glyph="delete" size={32} className="delete-button post-reaction" onClick={() => deletePost(id)} />}
         </footer>
       </section>
     </>

From 5e17482fb6c8ef9c9f4d91e17acb19be589bebc2 Mon Sep 17 00:00:00 2001
From: JosiasAurel <ndjosiasaurel@gmail.com>
Date: Sat, 31 Aug 2024 05:53:41 +0100
Subject: [PATCH 6/8] remove userID prop

---
 components/posts.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/components/posts.js b/components/posts.js
index 5265c75a..a0d98e02 100644
--- a/components/posts.js
+++ b/components/posts.js
@@ -70,7 +70,6 @@ const Posts = ({ posts = [], swrKey = null }) => {
         {posts.map(post => (
           <Post
             key={post.id}
-            userID={post.user.id}
             openEmojiPicker={openEmojiPicker}
             authStatus={status}
             authSession={session}

From 3d6ee87aaacf89c9cb75dd9413e4a011b6b380f4 Mon Sep 17 00:00:00 2001
From: JosiasAurel <ndjosiasaurel@gmail.com>
Date: Sat, 31 Aug 2024 05:59:11 +0100
Subject: [PATCH 7/8] remove func to get session user id

---
 components/post.js | 19 +------------------
 1 file changed, 1 insertion(+), 18 deletions(-)

diff --git a/components/post.js b/components/post.js
index 33db1046..16191734 100644
--- a/components/post.js
+++ b/components/post.js
@@ -206,21 +206,4 @@ const Post = ({
   )
 }
 
-export default Post
-
-const getSessionUserID = async (id) => {
-  try {
-    const response = await fetch('/api/web/session/get', {
-      method: 'POST',
-      headers: {
-        'Content-Type': 'application/json',
-      },
-      body: JSON.stringify({ id })
-    });
-
-    const responseText = await response.json();
-    return responseText.message;
-  } catch (error) {
-    console.error('Error:', error);
-  }
-}
\ No newline at end of file
+export default Post
\ No newline at end of file

From 7e23d597d1b901dde724add87bcece45d7f6ffb6 Mon Sep 17 00:00:00 2001
From: JosiasAurel <ndjosiasaurel@gmail.com>
Date: Sat, 31 Aug 2024 05:59:58 +0100
Subject: [PATCH 8/8] remove get.js

---
 pages/api/web/session/get.js | 31 -------------------------------
 1 file changed, 31 deletions(-)
 delete mode 100644 pages/api/web/session/get.js

diff --git a/pages/api/web/session/get.js b/pages/api/web/session/get.js
deleted file mode 100644
index 0b20b052..00000000
--- a/pages/api/web/session/get.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import { getServerSession } from 'next-auth/next';
-import { authOptions } from '../../auth/[...nextauth]';
-import prisma from '../../../../lib/prisma';
-
-export default async (req, res) => {
-    const session = await getServerSession(req, res, authOptions);
-
-    if (!session?.user) {
-        console.log('Unauthorized access attempt');
-        return res.status(401).send({ message: "Unauthorized" });
-    }
-
-    try {
-        const update = await prisma.session.findFirst({
-            where: {
-                userId: req.body.id
-            },
-            orderBy: {
-                expires: 'desc'
-            }
-        });
-        if (update) {
-            const userId = update.userId;
-            return res.status(200).send({ message: userId });
-        }
-        return res.status(200).send({ message: false });
-    } catch (e) {
-        console.error('Error deleting post:', e);
-        return res.status(500).json({ error: true, message: 'Internal Server Error' });
-    }
-};