updates to friend route, some changes to ui components, front end api tools

This commit is contained in:
Mikayla Dobson
2022-12-01 21:52:54 -06:00
parent 8a7eaa7db6
commit 2e48231dc5
10 changed files with 152 additions and 19 deletions

View File

@@ -30,6 +30,10 @@ const AboutYou: RegisterVariantType = ({ transitionDisplay }) => {
setInput(received); setInput(received);
}, []); }, []);
useEffect(() => {
if (authContext.user) navigate('/');
}, [authContext]);
const formConfig: FormConfig<IUser> = { const formConfig: FormConfig<IUser> = {
parent: "register", parent: "register",
keys: ['firstname', 'lastname', 'handle', 'email', 'password'], keys: ['firstname', 'lastname', 'handle', 'email', 'password'],

View File

@@ -1,20 +1,49 @@
import { ChangeEvent, useEffect, useState } from "react"; import { Button, Divider, Page, Panel, TextField, UserCard } from "../../ui";
import { ChangeEvent, useCallback, useEffect, useState } from "react";
import { RegisterVariantType, VariantLabel } from "."; import { RegisterVariantType, VariantLabel } from ".";
import { IUser } from "../../../schemas"; import { IUser } from "../../../schemas";
import { Button, Divider, Page, Panel, TextField, UserCard } from "../../ui"; import { getAllUsers } from "../../../util/apiUtils";
import { v4 } from 'uuid';
const AddFriends: RegisterVariantType = ({ transitionDisplay }) => { const AddFriends: RegisterVariantType = ({ transitionDisplay }) => {
const [searchTerm, setSearchTerm] = useState<string>(); const [searchTerm, setSearchTerm] = useState<string>();
const [friendResults, setFriendResults] = useState<IUser[]>(); const [userPool, setUserPool] = useState<IUser[]>([]);
const [friendResults, setFriendResults] = useState<IUser[]>([]);
const handleClick = async () => { const handleClick = async () => {
transitionDisplay(VariantLabel.FinishUp); transitionDisplay(VariantLabel.FinishUp);
} }
// this isn't really working right now i don't think
const handleRequestSent = useCallback((targetid: string | number) => {
setUserPool((prev: IUser[]) => {
const newResults = prev.filter((user: IUser) => {
return user.id !== targetid;
})
return newResults;
})
}, [])
// load available user pool on mount
useEffect(() => { useEffect(() => {
// run search when state changes and store it in friendresults (async function() {
console.log(searchTerm); const result = await getAllUsers();
}, [searchTerm]) if (result) setUserPool(result);
})();
}, [])
useEffect(() => {
if (!searchTerm) {
setFriendResults(new Array<IUser>());
} else {
const narrowedPool = userPool?.filter((person: IUser) => {
if (person.firstname.toLowerCase().includes(searchTerm) || person.lastname.toLowerCase().includes(searchTerm) || person.handle.toLowerCase().includes(searchTerm)) return person;
})
setFriendResults(narrowedPool);
}
}, [userPool, searchTerm])
return ( return (
<Page> <Page>
@@ -31,11 +60,11 @@ const AddFriends: RegisterVariantType = ({ transitionDisplay }) => {
<h3>If you know their email or unique handle, type it in below!</h3> <h3>If you know their email or unique handle, type it in below!</h3>
<div id="friend-search-widget"> <div id="friend-search-widget">
<TextField onChange={(e: ChangeEvent<HTMLInputElement>) => setSearchTerm(e.target.value)} placeholder={'Search'} /> <TextField onChange={(e: ChangeEvent<HTMLInputElement>) => setSearchTerm(e.target.value.toLowerCase())} placeholder={'Search'} />
{ {
friendResults && friendResults.map((friend: IUser) => { friendResults && friendResults.map((friend: IUser) => {
return <UserCard user={friend} /> return <UserCard key={v4()} user={friend} canAdd liftData={() => handleRequestSent(friend.id!)} />
}) })
} }
</div> </div>

View File

@@ -1,7 +1,6 @@
import { FC, useCallback, useState } from "react"; import { FC, useEffect, useState } from "react";
import { useAuthContext } from "../../../context/AuthContext"; import { useAuthContext } from "../../../context/AuthContext";
import { IUser } from "../../../schemas"; import { IUser } from "../../../schemas";
import { Page } from "../../ui";
import AboutYou from "./aboutyou"; import AboutYou from "./aboutyou";
import AddFriends from "./addfriends"; import AddFriends from "./addfriends";
import InitialCollection from "./collection"; import InitialCollection from "./collection";

View File

@@ -1,10 +1,10 @@
import { ButtonComponent } from "../../util/types" import { ButtonComponent } from "../../util/types"
import "/src/sass/components/Button.scss"; import "/src/sass/components/Button.scss";
const Button: ButtonComponent = ({ onClick = (() => {}), children, extraStyles }) => { const Button: ButtonComponent = ({ onClick = (() => {}), children, extraStyles, disabled = false, disabledText = null }) => {
return ( return (
<button onClick={onClick} className={`ui-button ${extraStyles || ''}`}> <button onClick={onClick} disabled={disabled} className={`ui-button ${extraStyles || ''}`}>
{ children || "Button" } { disabled ? (disabledText || children || "Button") : (children || "Button") }
</button> </button>
) )
} }

View File

@@ -1,12 +1,42 @@
import { useEffect, useState } from "react";
import { IUser } from "../../schemas";
import { addFriend, getPendingFriendRequests } from "../../util/apiUtils";
import { UserCardType } from "../../util/types"; import { UserCardType } from "../../util/types";
import Button from "./Button";
import Card from "./Card"; import Card from "./Card";
const UserCard: UserCardType = ({ extraStyles, user }) => { const UserCard: UserCardType = ({ extraStyles, user, canAdd = false, liftData }) => {
const [shouldDisable, setShouldDisable] = useState<boolean>(false);
useEffect(() => {
(async function() {
const requestsOpen = await getPendingFriendRequests();
if (!requestsOpen) return;
for (let req of requestsOpen) {
if (req.targetid == user.id) {
setShouldDisable(true);
console.log(req);
return;
}
}
setShouldDisable(false);
})();
}, [])
const handleClick = async () => {
const { id } = user;
const request = await addFriend(id!.toString());
if (request) console.log("Friend request sent to " + user.firstname);
}
return ( return (
<Card extraStyles={extraStyles}> <Card extraStyles={'user-card' + extraStyles}>
<div className="avatar"></div> <div className="avatar"></div>
<h3>{user.firstname} {user.lastname.substring(0,1)}.</h3> <h3>{user.firstname} {user.lastname.substring(0,1)}.</h3>
<h4>@{user.handle}</h4> <h4>@{user.handle}</h4>
{ canAdd && <Button disabledText={"Request Sent"} disabled={shouldDisable} onClick={handleClick}>Add Me</Button> }
</Card> </Card>
) )
} }

View File

@@ -10,7 +10,7 @@ export const getBaseAPI = async () => {
return fetch(API); return fetch(API);
} }
// auth and general user handlers // auth and general user management handlers
export const checkCredientials = async () => { export const checkCredientials = async () => {
try { try {
const response = await axios({ const response = await axios({
@@ -81,7 +81,46 @@ export const createNewCollection = async (body: ICollection) => {
} }
} }
// for user friendships // for users and user friendships
export const getAllUsers = async () => {
try {
const response = await axios({
method: "GET",
url: API + '/users'
})
return Promise.resolve(response.data);
} catch(e: any) {
throw e;
}
}
export const addFriend = async (id: string) => {
try {
const response = await axios({
method: "POST",
url: API + '/friend/' + id
})
return Promise.resolve(response.data);
} catch (e: any) {
throw e;
}
}
export const getPendingFriendRequests = async () => {
try {
const response = await axios({
method: "GET",
url: API + '/friend?pending=true'
})
return Promise.resolve(response.data);
} catch (e: any) {
throw e;
}
}
export const getFriendships = async () => { export const getFriendships = async () => {
try { try {
const response = await axios({ const response = await axios({

View File

@@ -10,6 +10,8 @@ interface PortalBase {
interface ButtonParams extends PortalBase { interface ButtonParams extends PortalBase {
onClick?: (params?: any) => any onClick?: (params?: any) => any
disabled?: boolean
disabledText?: string
} }
export interface MultiChildPortal extends PortalBase { export interface MultiChildPortal extends PortalBase {
@@ -18,6 +20,8 @@ export interface MultiChildPortal extends PortalBase {
interface UserCardProps extends PortalBase { interface UserCardProps extends PortalBase {
user: IUser user: IUser
canAdd?: boolean
liftData?: (data: any) => void
} }
interface NavbarProps { interface NavbarProps {

View File

@@ -64,6 +64,16 @@ export default class UserCtl {
} }
} }
async getPendingFriendRequests(senderid: string | number) {
try {
const { ok, code, result } = await UserInstance.getPendingFriendRequests(senderid);
if (ok) return result;
throw createError(code, result);
} catch (e: any) {
throw new Error(e);
}
}
async addFriendship(userid: number | string, targetid: number | string) { async addFriendship(userid: number | string, targetid: number | string) {
try { try {
const result = await UserInstance.addFriendship(userid, targetid); const result = await UserInstance.addFriendship(userid, targetid);

View File

@@ -123,6 +123,18 @@ export class User {
} }
} }
async getPendingFriendRequests(senderid: number | string) {
try {
const statement = `SELECT * FROM recipin.cmp_userfriendships WHERE pending = true AND senderid = $1`
const result = await pool.query(statement, [senderid]);
if (result.rows.length) return { ok: true, code: 200, result: result.rows }
return { ok: true, code: 200, result: "No pending friend requests found" }
} catch (e: any) {
throw new Error(e);
}
}
async addFriendship(userid: number | string, targetid: number | string) { async addFriendship(userid: number | string, targetid: number | string) {
try { try {
const statement = ` const statement = `

View File

@@ -23,10 +23,16 @@ export const friendRouter = (app: Express) => {
// get all friendships for a user // get all friendships for a user
router.get('/', async (req, res, next) => { router.get('/', async (req, res, next) => {
const { user }: any = req.user; const { user }: any = req.user;
const { pending } = req.query;
try { try {
const result = await UserInstance.getFriends(user.id); if (pending) {
res.status(200).send(result); const result = await UserInstance.getPendingFriendRequests(user.id);
res.status(200).send(result);
} else {
const result = await UserInstance.getFriends(user.id);
res.status(200).send(result);
}
} catch(e) { } catch(e) {
next(e); next(e);
} }