diff --git a/backend/models/user.js b/backend/models/user.js index d5d7551..d9af263 100644 --- a/backend/models/user.js +++ b/backend/models/user.js @@ -62,5 +62,7 @@ const userSchema = new Schema( } ); +userSchema.index({ username: "text" }); + const User = mongoose.model("User", userSchema); module.exports = { User }; diff --git a/backend/routes/user.js b/backend/routes/user.js index 1f7136e..b2042f4 100644 --- a/backend/routes/user.js +++ b/backend/routes/user.js @@ -75,11 +75,13 @@ router.get( // TO BE TESTED // add a friend router.post( - "/:userid/friends/:friendid", + "/:userid/friends/:friendusername", checkAuth, catchAsync(async (req, res, next) => { - let { friendid } = req.params; - let friendData = await User.findById(friendid); + let { friendusername } = req.params; + if (req.userData.username === friendusername) + res.json({ success: false, error: { message: "Cannot add yourself as friend" } }); + let friendData = await User.findOne({ username: friendusername }); if (friendData) { if (friendData.friends.includes(req.userData._id)) { res.json({ success: false, error: { message: "User is already added as a friend" } }); @@ -91,7 +93,7 @@ router.post( res.json({ success: true }); } } else { - res.status(404).json({ success: false, error: { message: "No user with the given username found" } }); + res.status(404).json({ success: false, error: { message: "username does not exist" } }); } }) ); diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a70ad43..eee2ed8 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,6 +11,7 @@ "@dnd-kit/core": "^6.0.8", "@emotion/react": "^11.11.1", "@mantine/core": "^6.0.14", + "@mantine/form": "^6.0.16", "@mantine/hooks": "^6.0.14", "@radix-ui/react-icons": "^1.3.0", "@tabler/icons-react": "^2.23.0", @@ -1095,6 +1096,18 @@ "react-dom": ">=16.8.0" } }, + "node_modules/@mantine/form": { + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/@mantine/form/-/form-6.0.16.tgz", + "integrity": "sha512-4TwxJKGQQRx7rj5yb9WgS0z/Ud8ckg0mMCiD3grKTxDCp0g8Tvk2Df7ptWFx2n+hxhBYVwMQSKggWuuDMFWBNA==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "klona": "^2.0.5" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/@mantine/hooks": { "version": "6.0.14", "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-6.0.14.tgz", @@ -2285,8 +2298,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", @@ -3010,6 +3022,14 @@ "node": ">=4.0" } }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "engines": { + "node": ">= 8" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index 92ecdba..f7993d6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,6 +13,7 @@ "@dnd-kit/core": "^6.0.8", "@emotion/react": "^11.11.1", "@mantine/core": "^6.0.14", + "@mantine/form": "^6.0.16", "@mantine/hooks": "^6.0.14", "@radix-ui/react-icons": "^1.3.0", "@tabler/icons-react": "^2.23.0", diff --git a/frontend/src/pages/Settings/Friends.jsx b/frontend/src/pages/Settings/Friends.jsx index dda88f2..6fdb28e 100644 --- a/frontend/src/pages/Settings/Friends.jsx +++ b/frontend/src/pages/Settings/Friends.jsx @@ -1,34 +1,37 @@ +import React from 'react' import { Button, Card, Flex, List, Stack, TextInput, Title } from '@mantine/core' import { IconSearch } from '@tabler/icons-react' -import React from 'react' +import { useForm } from '@mantine/form' +import { getAuthToken, getUserData } from '../../../utils/auth' +import FriendsList from '../../components/FriendsList' const Friends = () => { + let { id: userid } = getUserData(); + const form = useForm({ initialValues: { username: '' }, }) + + const addFriend = async () => { + const response = await fetch(`${import.meta.env.VITE_BACKEND_HOST}/api/user/${userid}/friends/${form.values.username}`, { + method: 'POST', + headers: { + 'Authorization': `Bearer ${getAuthToken()}` + } + }); + const resData = await response.json(); + if (resData.success === false) { + form.setErrors({ username: resData.error.message }) + } + } + return ( Friends - } /> - + } {...form.getInputProps('username')} /> + - - { - friends.map(({ username }) => { - return ( - - {username} - - ) - }) - } - + ) } -const friends = [ - { username: 'moonpatel' }, - { username: 'user2' }, - { username: 'user3' } -] - export default Friends \ No newline at end of file