From 52517e8df0b7d3127c82ce06d081fdef81f537a9 Mon Sep 17 00:00:00 2001 From: Rolguard <76728853+Rolguard@users.noreply.github.com> Date: Fri, 9 Dec 2022 13:28:25 +1100 Subject: [PATCH 1/3] Added current friends and not friends flags to search bar component --- .../DoomBuddies/ProfileSearchBar.js | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/client/src/components/DoomBuddies/ProfileSearchBar.js b/client/src/components/DoomBuddies/ProfileSearchBar.js index c036462..41d571b 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 = 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,29 @@ 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) => { + // 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); if (e.target.value !== "") { - setFilteredResults(searchResults.filter((user) => { - return user.username.startsWith(e.target.value); - })) + const friendUsernames = getFriends().map((friendObj) => friendObj.username) + + if (currentFriends) { + setFilteredResults(searchResults.filter((user) => user.username in friendUsernames + && user.username.startsWith(e.target.value)).slice(0, 8)) + } + else if (notFriends) { + setFilteredResults(searchResults.filter((user) => !(user.username in friendUsernames) + && 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([]) } From 682c6c7fc4bef6154d1fb706cabd94c33eca9c7a Mon Sep 17 00:00:00 2001 From: Rolguard <76728853+Rolguard@users.noreply.github.com> Date: Fri, 9 Dec 2022 22:01:40 +1100 Subject: [PATCH 2/3] Fixed error in fetching and filtering friends for search bar results --- .../DoomBuddies/ProfileSearchBar.js | 14 +- .../src/components/LandingPage/LandingPage.js | 2 +- server/src/routes/users.js | 139 ++++++++++++++++++ 3 files changed, 148 insertions(+), 7 deletions(-) diff --git a/client/src/components/DoomBuddies/ProfileSearchBar.js b/client/src/components/DoomBuddies/ProfileSearchBar.js index 41d571b..c131340 100644 --- a/client/src/components/DoomBuddies/ProfileSearchBar.js +++ b/client/src/components/DoomBuddies/ProfileSearchBar.js @@ -31,7 +31,7 @@ export default function ProfileSearchBar({ currentFriends = false, notFriends = }, []); const getFriends = async () => { - const response = fetch("http://localhost:5000/users/friends/get", { + const response = await fetch("http://localhost:5000/users/friends/get", { method: "GET", headers: { "Content-type": "application/json" @@ -39,7 +39,7 @@ export default function ProfileSearchBar({ currentFriends = false, notFriends = credentials: "include", }) const friendsList = await response.json(); - return friendsList + return friendsList; } @@ -56,20 +56,22 @@ export default function ProfileSearchBar({ currentFriends = false, notFriends = // 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); + const friendResults = await getFriends(); + if (e.target.value !== "") { - const friendUsernames = getFriends().map((friendObj) => friendObj.username) + const friendUsernames = friendResults.map((friendObj) => friendObj.username) if (currentFriends) { - setFilteredResults(searchResults.filter((user) => user.username in friendUsernames + setFilteredResults(searchResults.filter((user) => friendUsernames.includes(user.username) && user.username.startsWith(e.target.value)).slice(0, 8)) } else if (notFriends) { - setFilteredResults(searchResults.filter((user) => !(user.username in friendUsernames) + setFilteredResults(searchResults.filter((user) => !(friendUsernames.includes(user.username)) && user.username.startsWith(e.target.value)).slice(0, 8)) } else { 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 }; From 51509009bcdf2890063e77d916800bebc7b6d4af Mon Sep 17 00:00:00 2001 From: Rolguard <76728853+Rolguard@users.noreply.github.com> Date: Fri, 9 Dec 2022 23:01:45 +1100 Subject: [PATCH 3/3] Re --- client/src/components/DoomBuddies/ProfileSearchBar.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/src/components/DoomBuddies/ProfileSearchBar.js b/client/src/components/DoomBuddies/ProfileSearchBar.js index c131340..7c10769 100644 --- a/client/src/components/DoomBuddies/ProfileSearchBar.js +++ b/client/src/components/DoomBuddies/ProfileSearchBar.js @@ -63,6 +63,7 @@ export default function ProfileSearchBar({ currentFriends = false, notFriends = const friendResults = await getFriends(); + if (e.target.value !== "") { const friendUsernames = friendResults.map((friendObj) => friendObj.username) @@ -71,6 +72,9 @@ export default function ProfileSearchBar({ currentFriends = false, notFriends = && 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)) }