diff --git a/client/src/App.tsx b/client/src/App.tsx index 653e17f..0d2c4ea 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -22,6 +22,7 @@ import GroceryListCollection from './components/pages/GroceryListCollection'; import { TokenType } from './util/types'; import './sass/App.scss'; import handleToken from './util/handleToken'; +import AddFriends from './components/pages/AddFriends'; function App() { const { setUser, token, setToken } = useAuthContext(); @@ -54,6 +55,7 @@ function App() { } /> } /> } /> + } /> {}} />} /> } /> } /> diff --git a/client/src/components/pages/AddFriends.tsx b/client/src/components/pages/AddFriends.tsx new file mode 100644 index 0000000..8c2fe86 --- /dev/null +++ b/client/src/components/pages/AddFriends.tsx @@ -0,0 +1,22 @@ +import Protect from "../../util/Protect" +import { Divider, Panel } from "../ui" +import FriendSearchWidget from "../ui/Widgets/NewFriendWidget" + +const AddFriends = () => { + return ( + +

Search for New Friends

+ + + + +

Use the widget below to search for new friends!

+ + + +
+
+ ) +} + +export default AddFriends \ No newline at end of file diff --git a/client/src/components/ui/Navbar/variants.tsx b/client/src/components/ui/Navbar/variants.tsx index 14b9fca..99afe4f 100644 --- a/client/src/components/ui/Navbar/variants.tsx +++ b/client/src/components/ui/Navbar/variants.tsx @@ -55,6 +55,7 @@ const LoggedIn = () => { dropdownActive && ( + diff --git a/client/src/components/ui/UserCard.tsx b/client/src/components/ui/UserCard.tsx index 2fd703c..b30b0fa 100644 --- a/client/src/components/ui/UserCard.tsx +++ b/client/src/components/ui/UserCard.tsx @@ -1,31 +1,38 @@ import { useEffect, useState } from "react"; -import { addFriend, getPendingFriendRequests } from "../../util/apiUtils"; +import { useAuthContext } from "../../context/AuthContext"; +import API from "../../util/API"; +// import { addFriend, getPendingFriendRequests } from "../../util/apiUtils"; import { UserCardType } from "../../util/types"; import Button from "./Button"; import Card from "./Card"; -const UserCard: UserCardType = ({ extraStyles, user, canAdd = false, liftData }) => { - const [shouldDisable, setShouldDisable] = useState(canAdd); - +const UserCard: UserCardType = ({ extraStyles, user }) => { + const { token } = useAuthContext(); + useEffect(() => { + if (!token) return; + (async function() { - const requestsOpen = await getPendingFriendRequests(); + const friends = new API.Friendship(token); + const requestsOpen = await friends.getPendingFriendRequests(); + console.log(requestsOpen); if (!requestsOpen) return; for (let req of requestsOpen) { if (req.targetid == user.id) { - setShouldDisable(true); + console.log('should disable'); return; } } - setShouldDisable(false); - })(); + console.log('should not disable'); + }); }, []) const handleClick = async () => { - const { id } = user; - const request = await addFriend(id!.toString()); + if (!token) return; + const friends = new API.Friendship(token); + const request = await friends.addFriend(user.id!.toString()); if (request) console.log("Friend request sent to " + user.firstname); } @@ -34,7 +41,7 @@ const UserCard: UserCardType = ({ extraStyles, user, canAdd = false, liftData })

{user.firstname} {user.lastname.substring(0,1)}.

@{user.handle}

- { canAdd && } + ) } diff --git a/client/src/components/ui/Widgets/NewFriendWidget.tsx b/client/src/components/ui/Widgets/NewFriendWidget.tsx new file mode 100644 index 0000000..3b2e89a --- /dev/null +++ b/client/src/components/ui/Widgets/NewFriendWidget.tsx @@ -0,0 +1,60 @@ +import { ChangeEvent, FC, useCallback, useEffect, useState } from "react"; +import { IUser } from "../../../schemas"; +import { TextField, UserCard } from ".."; +import { v4 } from "uuid"; +import API from "../../../util/API"; +import { useAuthContext } from "../../../context/AuthContext"; + +const FriendSearchWidget: FC<{}> = () => { + const { token } = useAuthContext(); + + const [searchTerm, setSearchTerm] = useState(); + const [userPool, setUserPool] = useState([]); + const [pendingRequests, setPendingRequests] = useState(); + const [friendResults, setFriendResults] = useState([]); + + // load available user pool on mount + useEffect(() => { + if (!token) return; + (async function() { + const users = new API.User(token); + const result = await users.getAll(); + if (result) setUserPool(result); + })(); + + (async function() { + const friends = new API.Friendship(token); + const result = await friends.getAll(); + setFriendResults(result); + })(); + }, []) + + useEffect(() => { + console.log(searchTerm); + searchTerm && setUserPool((prev) => { + const newPool = prev.filter(person => { + if (person.firstname.toLowerCase().includes(searchTerm) || person.lastname.toLowerCase().includes(searchTerm) || person.handle.toLowerCase().includes(searchTerm)) return person; + }) + + return newPool; + }) + }, [searchTerm]) + + useEffect(() => { + console.log(userPool); + }, [userPool]) + + return ( +
+ ) => setSearchTerm(e.target.value.toLowerCase())} placeholder={'Search'} /> + + { + userPool.map((friend: IUser) => { + return {}} /> + }) + } +
+ ) +} + +export default FriendSearchWidget; \ No newline at end of file diff --git a/client/src/util/API.ts b/client/src/util/API.ts index 69b4ed2..1b5da16 100644 --- a/client/src/util/API.ts +++ b/client/src/util/API.ts @@ -1,4 +1,4 @@ -import { AxiosHeaders, AxiosRequestHeaders, AxiosResponse } from "axios"; +import { AxiosError, AxiosHeaders, AxiosRequestHeaders, AxiosResponse } from "axios"; import { IUser, IUserAuth, IFriendship, IRecipe, IIngredient, ICollection, IGroceryList } from "../schemas"; import { default as _instance } from "./axiosInstance"; @@ -138,13 +138,31 @@ module API { export class Friendship extends RestController { constructor(token: string) { - super(Settings.getAPISTRING() + "/app/friends", token); + super(Settings.getAPISTRING() + "/app/friend", token); + } + + override async getAll() { + try { + const response = await this.instance.get(this.endpoint, this.headers); + return Promise.resolve(response.data); + } catch(e) { + const error = e as AxiosError; + if (error.response?.status == 404) { + console.log('no friends found'); + return []; + } + } } async getPendingFriendRequests() { const response = await this.instance.get(this.endpoint + "?pending=true", this.headers); return Promise.resolve(response.data); } + + async addFriend(id: string | number) { + const response = await this.instance.post(this.endpoint + `/${id}`, this.headers); + return Promise.resolve(response.data); + } } export class Recipe extends RestController { diff --git a/server/routes/friend.ts b/server/routes/friend.ts index 42037a0..08561b9 100644 --- a/server/routes/friend.ts +++ b/server/routes/friend.ts @@ -9,19 +9,8 @@ const router = Router(); export const friendRouter = (app: Express) => { app.use('/app/friend', router); - router.use((req, res, next) => { - let test = req.session.user; - - if (req.session.user == undefined) { - throw new Error("No session found"); - } else { - const narrowed = req.session.user; - next(); - } - }) - router.post('/:targetid', restrictAccess, async (req, res, next) => { - const user = req.session.user as IUser; + const user = req.user as IUser; const { targetid } = req.params; try { @@ -34,7 +23,7 @@ export const friendRouter = (app: Express) => { // get all friendships for a user router.get('/', async (req, res, next) => { - const user = req.session.user as IUser; + const user = req.user as IUser; const { pending } = req.query; try { @@ -53,7 +42,7 @@ export const friendRouter = (app: Express) => { // get one friendship by its id router.get('/:id', async (req, res, next) => { const { id } = req.params; - const user = req.session.user as IUser; + const user = req.user as IUser; try { const { code, data } = await UserInstance.getFriendshipByID(id, user.id as number); @@ -76,7 +65,7 @@ export const friendRouter = (app: Express) => { router.put('/:id', async (req, res, next) => { const data = req.body; const { id } = req.params; - const user = req.session.user as IUser; + const user = req.user as IUser; try { const response = await UserInstance.updateFriendship(id, user.id as number, data); @@ -85,4 +74,6 @@ export const friendRouter = (app: Express) => { next(e); } }) + + return router; } \ No newline at end of file