Skip to content

Commit

Permalink
Update post and SinglePost page
Browse files Browse the repository at this point in the history
  • Loading branch information
tanish35 committed Oct 13, 2024
1 parent d4ceddd commit d8e0857
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 48 deletions.
5 changes: 5 additions & 0 deletions backend/src/controllers/postController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ const fetchPosts = asyncHandler(async (req: Request, res: Response) => {
pic: true,
},
},
_count: {
select: {
Comments: true,
},
},
},
take: postsPerPage,
skip: offset,
Expand Down
80 changes: 37 additions & 43 deletions frontend/src/components/Posts.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React, { useState, useEffect } from "react";
import {
Avatar,
Box,
Button,
Flex,
Text,
VStack,
Expand All @@ -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([]);
Expand All @@ -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",
{
Expand All @@ -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);
Expand Down Expand Up @@ -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",
Expand All @@ -149,36 +129,43 @@ const Posts = () => {
);
window.location.reload();
};
if (loading) {
return (
<Flex minH="100vh" align="center" justify="center" bg="black">
<InfinitySpin color="#3182CE" size={80} />
</Flex>

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 (
<Flex minH="100vh" align="center" justify="center" bg="black">
<InfinitySpin color="#3182CE" size={80} />
</Flex>
);
}

if (!userDetails) {
return <Navigate to="/login" />;
}

if (userDetails.username === null) {
return <Navigate to={`/addusername/${userDetails.user_id}`} />;
}

return (
<Container centerContent>
<SearchBar />
{communities && (
<CreatePost communities={communities} onSubmit={handleCreatePost} />
)}

<Stack direction="row" spacing={4} mb={4} width="100%" paddingTop={5}>
<Select value={selectedCommunity} onChange={handleCommunityChange}>
<option value="all">All</option>

{allCommunities.map((community) => (
<option key={community.college_id} value={community.college_id}>
{community.name}
Expand All @@ -187,7 +174,7 @@ const Posts = () => {
</Select>
</Stack>

<VStack spacing={4} align="stretch" width="100%" mt={4}>
<VStack spacing={6} align="stretch" width="100%" mt={4}>
<InfiniteScroll
dataLength={posts.length}
next={fetchPosts}
Expand All @@ -196,15 +183,19 @@ const Posts = () => {
>
{posts.map((post) => (
<Box
ref={postRef}
key={post.post_id}
p={4}
p={6}
borderWidth={1}
borderColor="gray.200"
borderRadius="lg"
boxShadow="lg"
width="100%"
marginTop={3}
mt={6}
className="transition transform hover:-translate-y-1 hover:shadow-2xl duration-300"
onClick={() => handlePostClick(post.post_id)}
>
<Flex align="center" mb={2}>
<Flex align="center" mb={4}>
<Avatar src={post.User.pic} size="md" mr={4} />
<Heading size="md">{post.title}</Heading>
</Flex>
Expand All @@ -215,16 +206,19 @@ const Posts = () => {
{post.User.username}
</Text>
<Text>{post.content}</Text>
<Flex justify="space-between" align="center" mt={2}>

<Flex justify="space-between" align="center" mt={4}>
<Flex align="center">
<Button size="sm" onClick={() => handleLike(post.post_id)}>
Like
</Button>
<Text ml={2}>
<Text className="text-sm text-white bg-blue-500 rounded-md px-2 py-1 shadow-md">
{post.likes} {post.likes === 1 ? "like" : "likes"}
</Text>
</Flex>
<Button size="sm">Comments</Button>
<Flex align="center">
<Text className="text-sm text-white bg-green-500 rounded-md px-2 py-1 shadow-md">
{post._count.Comments}{" "}
{post._count.Comments === 1 ? "comment" : "comments"}
</Text>
</Flex>
</Flex>
</Box>
))}
Expand Down
67 changes: 62 additions & 5 deletions frontend/src/components/SinglePost.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand All @@ -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 {
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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"
>
<VStack spacing={4} align="start">
<Flex align="center" w="full">
Expand All @@ -148,11 +188,13 @@ const SinglePost = () => {
<Flex w="full" justify="space-between" align="center" mt={4}>
<Flex align="center">
<Button
ref={likeButtonRef}
colorScheme="teal"
size="sm"
variant="outline"
onClick={() => handleLike(post.post_id)}
leftIcon={postLiked ? <AiFillLike /> : <GrLike />}
className="like-button"
>
{postLiked ? "Liked" : "Like"}
</Button>
Expand All @@ -164,6 +206,21 @@ const SinglePost = () => {
Comments
</Button>
</Flex>
<Box
ref={likeFloodRef}
className="like-flood-animation"
style={{
position: "absolute",
top: "50%",
left: "50%",
opacity: 0,
transform: "translate(-50%, -50%)",
fontSize: "2rem",
pointerEvents: "none",
}}
>
💖💖💖💖💖💖💖💖💖💖💖💖
</Box>
<Box mt={6} w="full">
<Heading size="md" mb={4} color="whiteAlpha.900">
Comments
Expand All @@ -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}
Expand Down

0 comments on commit d8e0857

Please sign in to comment.