diff --git a/backend/Controllers/UserController.js b/backend/Controllers/UserController.js
index a1defd1..eeae297 100644
--- a/backend/Controllers/UserController.js
+++ b/backend/Controllers/UserController.js
@@ -465,11 +465,55 @@ const toggleFollowUser = async (req, res) => {
+
+import mongoose from "mongoose";
+
+const getFollowerAndFollowingList = async (req, res) => {
+ const { id } = req.params; // Get the user ID from route params
+
+ // Check if the user ID is valid (mongoose checks for ObjectId format)
+ if (!mongoose.Types.ObjectId.isValid(id)) {
+ return res.status(400).json({ message: "Invalid user ID" });
+ }
+
+ try {
+ // Find the user with the provided ID
+ const user = await User.findById(id);
+
+ if (!user) {
+ return res.status(404).json({ message: "User not found" });
+ }
+
+ // Fetch the followers' details
+ const followers = await User.find({ '_id': { $in: user.followers } })
+ .select('firstName lastName username profile'); // Only select necessary fields
+
+ // Fetch the following details
+ const following = await User.find({ '_id': { $in: user.following } })
+ .select('firstName lastName username profile'); // Only select necessary fields
+
+ // Return the followers and following data
+ return res.json({
+ followers,
+ following,
+ });
+ } catch (err) {
+ console.error("Error fetching followers and following", err);
+ return res.status(500).json({ message: "Server error" });
+ }
+};
+
+export { getFollowerAndFollowingList };
+
+
+
+
const UserController = {
Signup,
Login,
getAllUserName,
toggleFollowUser,
+ getFollowerAndFollowingList,
deleteUserById,
verifyUserByToken,
forgotPassword,
diff --git a/backend/routes/web.js b/backend/routes/web.js
index 9c94815..5fe6703 100644
--- a/backend/routes/web.js
+++ b/backend/routes/web.js
@@ -20,6 +20,7 @@ router.get("/verify-account", VerificationController.verifyEmail);
router.post("/reverify-account", VerificationController.resendVerificationEmail);
router.post("/login", UserController.Login);
+router.get("/user/:id/followers-following", UserController.getFollowerAndFollowingList);
router.post("/submitFeedback", UserController.submitFeedback);
router.post("/follow", UserController.toggleFollowUser);
router.get('/feedback', UserController.getAllFeedback);
diff --git a/frontend/src/Components/FollowerModal.jsx b/frontend/src/Components/FollowerModal.jsx
new file mode 100644
index 0000000..b5abf94
--- /dev/null
+++ b/frontend/src/Components/FollowerModal.jsx
@@ -0,0 +1,67 @@
+// FollowModal.js
+import React from 'react';
+
+export default function FollowModal({ isOpen, onClose, followers, following, activeTab, setActiveTab }) {
+ console.log(following)
+ if (!isOpen) return null;
+
+ return (
+
+
+
+
Followers & Following
+
+
+
+ {/* Tab Header */}
+
+
+
+
+
+ {/* Tab Content */}
+
+ {activeTab === 'followers' ? (
+ followers.length > 0 ? (
+ followers.map((follower) => (
+
+
+
+ @{follower.username}
+ {follower.firstName} {follower.lastName}
+
+
+ ))
+ ) : (
+
No followers found.
+ )
+ ) : (
+ following.length > 0 ? (
+ following.map((followedUser) => (
+
+
+
+ @{followedUser.username}
+ {followedUser.firstName} {followedUser.lastName}
+
+
+ ))
+ ) : (
+
No following users found.
+ )
+ )}
+
+
+
+ );
+}
diff --git a/frontend/src/Pages/Profile.jsx b/frontend/src/Pages/Profile.jsx
index 083caa5..faf1b5b 100644
--- a/frontend/src/Pages/Profile.jsx
+++ b/frontend/src/Pages/Profile.jsx
@@ -1,6 +1,6 @@
import { useState, useEffect } from 'react'
import { useParams, useLocation } from 'react-router-dom'
-
+import FollowModal from '../Components/FollowerModal'
import axios from 'axios'
export default function UserProfile() {
@@ -9,7 +9,8 @@ export default function UserProfile() {
const token = JSON.parse(localStorage.getItem("tastytoken")) // Token still comes from local storage for authentication
const [user, setUser] = useState(null)
-
+const [followingList, setFollowingList] = useState(null)
+ const [followersList, setFollowersList] = useState(null);
const [username, setUsername] = useState("ChefJulia")
const [bio, setBio] = useState("Passionate about creating delicious, healthy recipes that anyone can make!")
const [imagePreview, setImagePreview] = useState("/placeholder.svg?height=128&width=128")
@@ -48,6 +49,7 @@ export default function UserProfile() {
useEffect(() => {
+ if (user) {
// Fetch user information
const fetchUserImage = () => {
axios
@@ -113,8 +115,8 @@ export default function UserProfile() {
fetchUserImage()
fetchRecipes()
fetchLikedRecipes() // Call the fetchLikedRecipes function to get liked recipes
-
- }, [id, backendURL, token, user]) // Use id, backendURL, and token in dependencies
+ }
+ }, [user])
const handleFollow = async () => {
try {
@@ -128,8 +130,34 @@ export default function UserProfile() {
console.error("Error updating follow status", err);
}
};
+ useEffect(() => {
+ if(user){
+ const fetchFollowersFollowing = async () => {
+ try {
+ const response = await axios.get(`${backendURL}/api/user/${id}/followers-following`);
+ setFollowersList(response.data.followers);
+ setFollowingList(response.data.following);
+ console.log(response)
+ setLoading(false);
+ } catch (err) {
+ setError("Error fetching data");
+ setLoading(false);
+ }
+ };
+
+ fetchFollowersFollowing();
+ }
+ }, [user]);
+ const [isModalOpen, setIsModalOpen] = useState(false);
+ const [activeModalTab, setActiveModalTab] = useState('followers'); // Tracks which tab to show in modal
+ const handleOpenModal = (tab) => {
+ setActiveModalTab(tab);
+ setIsModalOpen(true);
+ };
+
+ const handleCloseModal = () => setIsModalOpen(false);
return (
{/* Banner and Profile Picture */}
@@ -155,23 +183,31 @@ export default function UserProfile() {
{username}
{bio}
+ {(user && (user.user._id !== id)) &&
+ className={`px-4 py-2 rounded-full ${
+ following
+ ? 'bg-white text-red-700 border border-red-700 hover:bg-red-50'
+ : 'bg-red-700 text-white hover:bg-red-800'
+ }`}
+ onClick={handleFollow}
+ >
+ {following ? 'Following' : 'Follow'}
+ }
+
{/* User Stats */}
{recipes.length} Recipes
- {followers} Followers
- {followingCount} Following
+
+
+
+
@@ -252,6 +288,14 @@ export default function UserProfile() {
)}
+
)
}