updates to friend route, some changes to ui components, front end api tools
This commit is contained in:
@@ -30,6 +30,10 @@ const AboutYou: RegisterVariantType = ({ transitionDisplay }) => {
|
||||
setInput(received);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (authContext.user) navigate('/');
|
||||
}, [authContext]);
|
||||
|
||||
const formConfig: FormConfig<IUser> = {
|
||||
parent: "register",
|
||||
keys: ['firstname', 'lastname', 'handle', 'email', 'password'],
|
||||
|
||||
@@ -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 { 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 [searchTerm, setSearchTerm] = useState<string>();
|
||||
const [friendResults, setFriendResults] = useState<IUser[]>();
|
||||
const [userPool, setUserPool] = useState<IUser[]>([]);
|
||||
const [friendResults, setFriendResults] = useState<IUser[]>([]);
|
||||
|
||||
const handleClick = async () => {
|
||||
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(() => {
|
||||
// run search when state changes and store it in friendresults
|
||||
console.log(searchTerm);
|
||||
}, [searchTerm])
|
||||
(async function() {
|
||||
const result = await getAllUsers();
|
||||
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 (
|
||||
<Page>
|
||||
@@ -31,11 +60,11 @@ const AddFriends: RegisterVariantType = ({ transitionDisplay }) => {
|
||||
<h3>If you know their email or unique handle, type it in below!</h3>
|
||||
|
||||
<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) => {
|
||||
return <UserCard user={friend} />
|
||||
return <UserCard key={v4()} user={friend} canAdd liftData={() => handleRequestSent(friend.id!)} />
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { FC, useCallback, useState } from "react";
|
||||
import { FC, useEffect, useState } from "react";
|
||||
import { useAuthContext } from "../../../context/AuthContext";
|
||||
import { IUser } from "../../../schemas";
|
||||
import { Page } from "../../ui";
|
||||
import AboutYou from "./aboutyou";
|
||||
import AddFriends from "./addfriends";
|
||||
import InitialCollection from "./collection";
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { ButtonComponent } from "../../util/types"
|
||||
import "/src/sass/components/Button.scss";
|
||||
|
||||
const Button: ButtonComponent = ({ onClick = (() => {}), children, extraStyles }) => {
|
||||
const Button: ButtonComponent = ({ onClick = (() => {}), children, extraStyles, disabled = false, disabledText = null }) => {
|
||||
return (
|
||||
<button onClick={onClick} className={`ui-button ${extraStyles || ''}`}>
|
||||
{ children || "Button" }
|
||||
<button onClick={onClick} disabled={disabled} className={`ui-button ${extraStyles || ''}`}>
|
||||
{ disabled ? (disabledText || children || "Button") : (children || "Button") }
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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 Button from "./Button";
|
||||
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 (
|
||||
<Card extraStyles={extraStyles}>
|
||||
<Card extraStyles={'user-card' + extraStyles}>
|
||||
<div className="avatar"></div>
|
||||
<h3>{user.firstname} {user.lastname.substring(0,1)}.</h3>
|
||||
<h4>@{user.handle}</h4>
|
||||
{ canAdd && <Button disabledText={"Request Sent"} disabled={shouldDisable} onClick={handleClick}>Add Me</Button> }
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export const getBaseAPI = async () => {
|
||||
return fetch(API);
|
||||
}
|
||||
|
||||
// auth and general user handlers
|
||||
// auth and general user management handlers
|
||||
export const checkCredientials = async () => {
|
||||
try {
|
||||
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 () => {
|
||||
try {
|
||||
const response = await axios({
|
||||
|
||||
@@ -10,6 +10,8 @@ interface PortalBase {
|
||||
|
||||
interface ButtonParams extends PortalBase {
|
||||
onClick?: (params?: any) => any
|
||||
disabled?: boolean
|
||||
disabledText?: string
|
||||
}
|
||||
|
||||
export interface MultiChildPortal extends PortalBase {
|
||||
@@ -18,6 +20,8 @@ export interface MultiChildPortal extends PortalBase {
|
||||
|
||||
interface UserCardProps extends PortalBase {
|
||||
user: IUser
|
||||
canAdd?: boolean
|
||||
liftData?: (data: any) => void
|
||||
}
|
||||
|
||||
interface NavbarProps {
|
||||
|
||||
@@ -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) {
|
||||
try {
|
||||
const result = await UserInstance.addFriendship(userid, targetid);
|
||||
|
||||
@@ -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) {
|
||||
try {
|
||||
const statement = `
|
||||
|
||||
@@ -23,10 +23,16 @@ export const friendRouter = (app: Express) => {
|
||||
// get all friendships for a user
|
||||
router.get('/', async (req, res, next) => {
|
||||
const { user }: any = req.user;
|
||||
const { pending } = req.query;
|
||||
|
||||
try {
|
||||
const result = await UserInstance.getFriends(user.id);
|
||||
res.status(200).send(result);
|
||||
if (pending) {
|
||||
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) {
|
||||
next(e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user