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);
|
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'],
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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({
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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 = `
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user