diff --git a/client/src/components/DoomBuddies/ProfileSearchBar.js b/client/src/components/DoomBuddies/ProfileSearchBar.js index c036462..7c10769 100644 --- a/client/src/components/DoomBuddies/ProfileSearchBar.js +++ b/client/src/components/DoomBuddies/ProfileSearchBar.js @@ -1,11 +1,12 @@ -import { TextField, InputAdornment, IconButton, Menu, MenuItem, Popper, ListItemIcon, ListItemText, ClickAwayListener } from "@mui/material"; +import { TextField, InputAdornment, IconButton, MenuItem, Popper, ListItemIcon, ListItemText, ClickAwayListener } from "@mui/material"; import SearchIcon from '@mui/icons-material/Search'; import PersonIcon from '@mui/icons-material/Person'; import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; -export default function ProfileSearchBar() { - // TODO: Empty string shows all search results in database +export default function ProfileSearchBar({ currentFriends = false, notFriends = false }) { + // By default, displays all users in the database + // Can specify filter for search results based on props const [searchInput, setSearchInput] = useState(""); const [searchResults, setSearchResults] = useState([]); @@ -29,6 +30,19 @@ export default function ProfileSearchBar() { getUsers(); }, []); + const getFriends = async () => { + const response = await fetch("http://localhost:5000/users/friends/get", { + method: "GET", + headers: { + "Content-type": "application/json" + }, + credentials: "include", + }) + const friendsList = await response.json(); + return friendsList; + } + + const openUserTracker = (user) => { // Open the page with the user's id console.log(user); @@ -39,16 +53,35 @@ export default function ProfileSearchBar() { e.preventDefault(); console.log(`Form submitted with input value ${searchInput}`); // If form is submitted should show page with list of profiles with closest matching usernames with search result + // Clicking search icon should do the same } - const handleChange = (e) => { + const handleChange = async (e) => { + // Filters search results based on how closely it matches with user input, + // And whether currentFriends or notFriends flags are true, maximum of 8 results shown setSearchInput(e.target.value); - console.log(e.target.value); + + const friendResults = await getFriends(); + if (e.target.value !== "") { - setFilteredResults(searchResults.filter((user) => { - return user.username.startsWith(e.target.value); - })) + const friendUsernames = friendResults.map((friendObj) => friendObj.username) + + if (currentFriends) { + setFilteredResults(searchResults.filter((user) => friendUsernames.includes(user.username) + && user.username.startsWith(e.target.value)).slice(0, 8)) + } + else if (notFriends) { + console.log(searchResults.filter((user) => !(friendUsernames.includes(user.username)) + && user.username.startsWith(e.target.value)).slice(0, 8)) + + setFilteredResults(searchResults.filter((user) => !(friendUsernames.includes(user.username)) + && user.username.startsWith(e.target.value)).slice(0, 8)) + } + else { + setFilteredResults(searchResults.filter((user) => user.username.startsWith(e.target.value)).slice(0, 8)) + } + } else { setFilteredResults([]) } diff --git a/client/src/components/LandingPage/LandingPage.js b/client/src/components/LandingPage/LandingPage.js index 42150cf..3d09225 100644 --- a/client/src/components/LandingPage/LandingPage.js +++ b/client/src/components/LandingPage/LandingPage.js @@ -7,7 +7,7 @@ import ProfileSearchBar from "../DoomBuddies/ProfileSearchBar"; export default function LandingPage() { return ( <> - +
{ } }); + +// GET - /users/friends/get +// given user, gets an array of friend +// objects with id, username and pfp +router.get("/friends/get", async (req, res, next) => { + + const userObj = req.authUser; + + if (userObj.friends === undefined) { + userObj.friends = []; + } + + const friendsList = []; + let friendObj = {}; + for (let i = 0; i < userObj.friends.length; i++) { + let friend = await doomUsers.findOne({ _id: ObjectId(userObj.friends[i]) }); + if (friend !== null) { + friendObj = { + _id: ObjectId(friend._id), + username: friend.username, + profileImg: friend.profileImg, + }; + } + friendsList.push(friendObj); + } + return res.send(friendsList); +}); + +// GET - /users/notFriends/get +// given user, gets an array of users +// objects with id, username and pfp +// that are NOT friends +router.get("/notFriends/get", async (req, res, next) => { + + const userObj = req.authUser; + + if (userObj.friends === undefined) { + userObj.friends = []; + } + + const friendsList = userObj.friends; + friendsList.push(userObj._id.toString()); + + const usersArray = await doomUsers.find().toArray(); + + for (const friend of friendsList) { + if (usersArray.find(e => e._id.toString() === friend) !== undefined) { + const friendIndex = usersArray.findIndex(e => e._id.toString() === friend); + usersArray.splice(friendIndex, 1); + } + } + + return res.send(usersArray); +}); + + +// POST - /users/friends/post +// given user and friend id, +// adds friend to user +router.post("/friends/post", async (req, res, next) => { + try { + const userObj = req.authUser; + const friendId = ObjectId(req.body._id); + + if (friendId === undefined) { + return res.status(400).send({ error: "friendId not given" }); + } + + let foundFriend = await doomUsers.findOne({ _id: ObjectId(friendId) }); + + if (foundFriend === null || foundFriend._id.toString() === userObj._id.toString()) { + return res.status(400).send({ error: "friendId is invalid" }); + } + + if (userObj.friends === undefined) { + userObj.friends = []; + } + + for (let friend of userObj.friends) { + if (friend === foundFriend._id.toString()) { + return res + .status(400) + .send({ error: "user already a friend" }); + } + } + + userObj.friends.push(foundFriend._id.toString()); + await doomUsers.updateOne({ _id: ObjectId(userObj._id) }, { $set: { friends: userObj.friends } }); + return res.send(userObj.friends); + } catch (error) { + next(error); + } +}); + +// DELETE - /users/friends/delete +// given user and friend id, +// deletes friend from user +router.delete("/friends/delete", async (req, res, next) => { + try { + const userObj = req.authUser; + const friendId = ObjectId(req.body._id); + + if (friendId === undefined) { + return res.status(400).send({ error: "friendId not given" }); + } + + let foundFriend = await doomUsers.findOne({ _id: ObjectId(friendId) }); + + if (foundFriend === null || foundFriend._id.toString() === userObj._id.toString()) { + return res.status(400).send({ error: "friendId is invalid" }); + } + + if (userObj.friends === undefined) { + userObj.friends = []; + } + + let flag = false; + for (let friend of userObj.friends) { + if (friend === foundFriend._id.toString()) { + flag = true; + break; + } + } + + if (flag === false) { + return res + .status(400) + .send({ error: "user isn't a friend" }); + } + + const friendIndex = userObj.friends.indexOf(foundFriend._id.toString()); + userObj.friends.splice(friendIndex, 1); + await doomUsers.updateOne({ _id: ObjectId(userObj._id) }, { $set: { friends: userObj.friends } }); + return res.send(userObj.friends); + } catch (error) { + next(error); + } +}); + export { router as default };