diff --git a/backend/src/controllers/postController.ts b/backend/src/controllers/postController.ts index 5d6a17d..51462ba 100644 --- a/backend/src/controllers/postController.ts +++ b/backend/src/controllers/postController.ts @@ -139,6 +139,11 @@ const fetchPosts = asyncHandler(async (req: Request, res: Response) => { pic: true, }, }, + _count: { + select: { + Comments: true, + }, + }, }, take: postsPerPage, skip: offset, diff --git a/frontend/src/components/Posts.jsx b/frontend/src/components/Posts.jsx index cf03096..3102861 100644 --- a/frontend/src/components/Posts.jsx +++ b/frontend/src/components/Posts.jsx @@ -2,7 +2,6 @@ import React, { useState, useEffect } from "react"; import { Avatar, Box, - Button, Flex, Text, VStack, @@ -20,7 +19,9 @@ import SearchBar from "./SearchBar"; import { useUser } from "../hook/useUser"; import Loader from "./loading"; import { InfinitySpin } from "react-loader-spinner"; -import { set } from "zod"; +import { gsap } from "gsap"; +import { useRef } from "react"; + const Posts = () => { const [posts, setPosts] = useState([]); const [communities, setCommunities] = useState([]); @@ -36,12 +37,7 @@ const Posts = () => { const fetchPosts = async () => { setLoading(true); try { - let collegeId; - if (selectedCommunity === "all") { - collegeId = null; - } else { - collegeId = selectedCommunity; - } + let collegeId = selectedCommunity === "all" ? null : selectedCommunity; const response = await axios.post( "/api/post/fetch", { @@ -54,7 +50,7 @@ const Posts = () => { ); const posts = response.data.posts; setPosts((prevPosts) => [...prevPosts, ...posts]); - if (response.data.isOver == true) { + if (response.data.isOver) { setHasMore(false); } setPage(page + 1); @@ -121,22 +117,6 @@ const Posts = () => { navigate(`/posts/${postId}`); }; - const handleLike = async (postId) => { - try { - await axios.post("/api/post/like", { postId }, { withCredentials: true }); - setPosts((prevPosts) => - prevPosts.map((post) => { - if (post.post_id === postId) { - return { ...post, likes: post.likes + 1 }; - } - return post; - }) - ); - } catch (error) { - console.error("Error liking post:", error); - } - }; - const handleCreatePost = async ({ title, content, community }) => { const response = await axios.post( "/api/post/create", @@ -149,36 +129,43 @@ const Posts = () => { ); window.location.reload(); }; - if (loading) { - return ( - - - + + const postRef = useRef(null); + + useEffect(() => { + gsap.fromTo( + postRef.current, + { opacity: 0, y: 20 }, + { opacity: 1, y: 0, duration: 0.6, stagger: 0.2 } ); - } - if (loadingUser) { + }, [posts]); + + if (loading || loadingUser) { return ( ); } + if (!userDetails) { return ; } + if (userDetails.username === null) { return ; } + return ( {communities && ( )} + - + { > {posts.map((post) => ( handlePostClick(post.post_id)} > - + {post.title} @@ -215,16 +206,19 @@ const Posts = () => { {post.User.username} {post.content} - + + - - + {post.likes} {post.likes === 1 ? "like" : "likes"} - + + + {post._count.Comments}{" "} + {post._count.Comments === 1 ? "comment" : "comments"} + + ))} diff --git a/frontend/src/components/SinglePost.jsx b/frontend/src/components/SinglePost.jsx index e6bd809..8f166a2 100644 --- a/frontend/src/components/SinglePost.jsx +++ b/frontend/src/components/SinglePost.jsx @@ -13,8 +13,9 @@ import { Center, VStack, } from "@chakra-ui/react"; +import { gsap } from "gsap"; import axios from "axios"; -import CreateComment from "./CreateComment"; // Import the CreateComment component +import CreateComment from "./CreateComment"; import { useUser } from "../hook/useUser"; import { InfinitySpin } from "react-loader-spinner"; @@ -25,6 +26,10 @@ const SinglePost = () => { const [postLiked, setPostLiked] = useState(false); const { userDetails, loadingUser } = useUser(); + // Refs for the animations + const likeButtonRef = React.useRef(null); + const likeFloodRef = React.useRef(null); + useEffect(() => { const fetchPost = async () => { try { @@ -74,6 +79,41 @@ const SinglePost = () => { } const handleLike = async (postId) => { + const timeline = gsap.timeline(); + + timeline.to(likeButtonRef.current, { + scale: 1.5, + duration: 0.2, + ease: "power2.inOut", + }); + timeline.to(likeButtonRef.current, { + scale: 1, + duration: 0.2, + ease: "power2.inOut", + }); + + if (!postLiked) { + gsap + .to(likeFloodRef.current, { + opacity: 1, + scale: 1, + duration: 0.5, + ease: "power2.out", + }) + .then(() => { + gsap.to(likeFloodRef.current, { + opacity: 0, + scale: 0, + duration: 0.5, + ease: "power2.in", + onComplete: () => { + // Hide the box after the animation is complete + gsap.set(likeFloodRef.current, { opacity: 0, scale: 1 }); + }, + }); + }); + } + if (postLiked) { try { await axios.post( @@ -121,11 +161,11 @@ const SinglePost = () => { maxW="3xl" mx="auto" mt={8} - bg="gray.900" // Dark background for the post box + bg="gray.900" borderRadius="md" boxShadow="lg" borderWidth={1} - color="whiteAlpha.900" // White text for contrast + color="whiteAlpha.900" > @@ -148,11 +188,13 @@ const SinglePost = () => { @@ -164,6 +206,21 @@ const SinglePost = () => { Comments + + 💖💖💖💖💖💖💖💖💖💖💖💖 + Comments @@ -179,8 +236,8 @@ const SinglePost = () => { key={comment.comment_id} p={4} mb={4} - bg="gray.800" // Darker background for comments - color="whiteAlpha.900" // White text for comments + bg="gray.800" + color="whiteAlpha.900" borderRadius="md" boxShadow="sm" borderWidth={1}