more customization on user/versus other-user profiles

This commit is contained in:
Mikayla Dobson
2023-02-14 14:19:19 -06:00
parent 9945ebadb4
commit 28c4747aba
8 changed files with 119 additions and 74 deletions

View File

@@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { FC, useEffect, useState } from "react";
import { v4 } from "uuid";
import { useAuthContext } from "../../context/AuthContext";
import { getAllUsers, getFriendships, getPendingFriendRequests, getUserByID } from "../../util/apiUtils";
@@ -8,7 +8,7 @@ import { IUser, IFriendship } from "../../schemas";
import { Card, Divider, Panel } from "../ui";
import FriendSearchWidget from "../ui/Widgets/FriendSearchWidget";
export default function Friends() {
const Friends: FC<{ targetUser?: IUser }> = ({ targetUser }) => {
const [friends, setFriends] = useState<IFriendship[]>();
const [userList, setUserList] = useState(new Array<IUser>());
const { user, token } = useAuthContext();
@@ -35,29 +35,35 @@ export default function Friends() {
if (!token || !friends) return;
friends.map(async (friend: IFriendship) => {
const Friends = new API.Friendship(token);
const userData = await Friends.getByID(friend.targetid as string);
const User = new API.User(token);
const userData = await User.getByID(friend.targetid as string);
if (userData) setUserList((prev: IUser[]) => {
return [...prev, userData]
if (prev.includes(userData)) {
return prev;
} else {
return [...prev, userData]
}
})
})
}, [friends]);
useEffect(() => {
console.log(userList);
}, [setUserList])
return (
<>
{ userList.length ?
(
<Card extraStyles="flex-row">
<h2>Your friendships:</h2>
<h2>Friends ({ userList?.length ?? "0" }):</h2>
{
userList.map((user: IUser) => {
return <UserCard key={v4()} user={user} />
return <UserCard key={v4()} targetUser={user} />
})
}
<aside>
<p>Looking for someone else?</p>
<p>You can search for more friends <a href="/add-friends">here!</a></p>
</aside>
</Card>
) :
(
@@ -74,3 +80,5 @@ export default function Friends() {
</>
)
}
export default Friends

View File

@@ -1,53 +1,67 @@
import { useEffect, useState } from "react";
import { v4 } from "uuid";
import { useAuthContext } from "../../context/AuthContext";
import { ICollection, IRecipe } from "../../schemas";
import { ICollection } from "../../schemas";
import API from "../../util/API";
import { Card, Page } from "../ui";
interface CollectionDetails {
idx: number
collection: ICollection
recipes: IRecipe[]
}
import { Page, Panel } from "../ui";
const CollectionBrowser = () => {
const [list, setList] = useState<ICollection[]>();
const { token } = useAuthContext();
async function getRecipeCount(collection: ICollection) {
if (!token) return [];
const collections = new API.Collection(token);
const result = await collections.getRecipesFromOne(collection.id);
if (result) return result;
return [];
}
async function mapRecipes() {
if (!list) return;
return list.map(async (each) => {
const count = await getRecipeCount(each);
return (
<Panel key={v4()}>
<h2>{each.name}</h2>
<p>{count.length} recipes</p>
<a href={`/collections/${each.id}`}>Link to details</a>
</Panel>
)
})
}
useEffect(() => {
if (!token) return;
(async() => {
const collections = new API.Collection(token);
const recipes = new API.Recipe(token);
const allRecipes = await collections.getAllAuthored();
if (allRecipes) {
const result = new Array<CollectionDetails[]>();
let i = 0;
for (let each of allRecipes) {
}
setList(allRecipes);
}
if (allRecipes) setList(allRecipes);
})();
}, [token])
useEffect(() => {
}, [list])
return (
<Page>
<h1>Browsing your {2} collections:</h1>
{ list && (
<>
<h1>Browsing your {list.length} collection{ (list.length !== 1) && "s" }:</h1>
{
list && list.map(each => {
{ list.map(each => {
return (
<Card key={v4()}>
<Panel key={v4()}>
<h2>{each.name}</h2>
<a href={`/collections/${each.id}`}>Link to details</a>
</Card>
</Panel>
)
})
}
})}
</>
)}
</Page>
)
}

View File

@@ -37,8 +37,6 @@ export default function Profile() {
isSet: false
});
const dateFormatter = new Intl.DateTimeFormat('en-US', { timeStyle: undefined, dateStyle: "long" });
// STEP 1: FETCH METADATA (requires token)
useEffect(() => {
if (!token || !user) return;
@@ -115,10 +113,6 @@ export default function Profile() {
}
})();
(async() => {
const Friends = new API.Friendship(token);
})
setMetadata((prev) => {
return {
...prev,
@@ -135,6 +129,8 @@ export default function Profile() {
// STEP 2: set up page UI based on profile config above
useEffect(() => {
if (metadata.isSet) {
// if this is another user's profile
if (metadata.targetUser) {
setContents(
<Protect redirect="/">
@@ -148,12 +144,12 @@ export default function Profile() {
</Panel>
<Panel>
<h2>My collections:</h2>
<h2>{metadata.targetUser.firstname}'s collections ({ metadata.collections.length ?? "0" }):</h2>
<CollectionList targetID={metadata.targetUser.id} />
</Panel>
<Panel>
<h2>My friends:</h2>
<h2>{metadata.targetUser.firstname}'s friends:</h2>
<Friends />
</Panel>
</div>
@@ -161,6 +157,8 @@ export default function Profile() {
</Protect>
)
} else {
// if this is the current user's profile
setContents(
<Protect redirect="profile">
<div className="profile-authenticated">
@@ -178,12 +176,11 @@ export default function Profile() {
<Panel>
{/* include number of collections */}
<h2>My collections ({ metadata.collections.length || 0 }):</h2>
<h2><a href="/collections">My collections</a> ({ metadata.collections.length || 0 }):</h2>
<CollectionList />
</Panel>
<Panel>
<h2>My friends:</h2>
<Friends />
</Panel>
</div>

View File

@@ -1,7 +1,7 @@
import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { Page, Panel } from "../ui";
import { IRecipe } from "../../util/types";
import { IRecipe } from "../../schemas";
import { getRecipeByID } from "../../util/apiUtils";
export default function Recipe() {

View File

@@ -1,47 +1,55 @@
import { AxiosError } from "axios";
import { useEffect, useState } from "react";
import { useAuthContext } from "../../context/AuthContext";
import API from "../../util/API";
// import { addFriend, getPendingFriendRequests } from "../../util/apiUtils";
import { UserCardType } from "../../util/types";
import API from "../../util/API";
import Button from "./Button";
import Card from "./Card";
const UserCard: UserCardType = ({ extraStyles, user }) => {
const UserCard: UserCardType = ({ extraStyles, targetUser }) => {
const [buttonVariant, setButtonVariant] = useState(<></>);
const { token } = useAuthContext();
useEffect(() => {
if (!token) return;
(async function() {
const friends = new API.Friendship(token);
const requestsOpen = await friends.getPendingFriendRequests();
console.log(requestsOpen);
if (!requestsOpen) return;
try {
const friends = new API.Friendship(token);
const requestsOpen = await friends.getPendingFriendRequests();
if (!requestsOpen) return;
for (let req of requestsOpen) {
if (req.targetid == user.id) {
console.log('should disable');
return;
for (let req of requestsOpen) {
if (req.targetid == targetUser.id) {
setButtonVariant(<Button disabled>Request Sent!</Button>)
return;
}
}
setButtonVariant(<Button onClick={handleClick}>Send Request</Button>)
} catch (error) {
if (error instanceof AxiosError) {
console.log(error.response?.statusText);
}
}
console.log('should not disable');
});
})();
}, [])
const handleClick = async () => {
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);
const request = await friends.addFriend(targetUser.id!.toString());
if (request) {
setButtonVariant(<Button disabled>Request Sent!</Button>)
}
}
return (
<Card extraStyles={'user-card' + extraStyles}>
<div className="avatar"></div>
<h3>{user.firstname} {user.lastname.substring(0,1)}.</h3>
<h4>@{user.handle}</h4>
<Button disabledText={"Request Sent"} onClick={handleClick}>Add Me</Button>
<h3><a href={`/profile?id=${targetUser.id}`}>{targetUser.firstname} {targetUser.lastname.substring(0,1)}.</a></h3>
<h4>@{targetUser.handle}</h4>
{ buttonVariant }
</Card>
)
}

View File

@@ -154,6 +154,19 @@ module API {
}
}
async getTargetUserFriendships(id: string | number) {
try {
const response = await this.instance.get(this.endpoint + `?targetUser=${id}`, 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);

View File

@@ -19,7 +19,7 @@ export interface ProtectParams extends PortalBase {
}
interface UserCardProps extends PortalBase {
user: IUser
targetUser: IUser
canAdd?: boolean
liftData?: (data: any) => void
}

View File

@@ -24,15 +24,20 @@ export const friendRouter = (app: Express) => {
// get all friendships for a user
router.get('/', async (req, res, next) => {
const user = req.user as IUser;
const { pending } = req.query;
const { pending, targetUser } = req.query;
try {
if (pending) {
const { code, data } = await UserInstance.getPendingFriendRequests(user.id as number);
res.status(code).send(data);
} else {
const { code, data } = await UserInstance.getFriends(user.id as number);
res.status(code).send(data);
if (targetUser) {
const { code, data } = await UserInstance.getFriends(parseInt(targetUser as string));
res.status(code).send(data);
} else {
const { code, data } = await UserInstance.getFriends(user.id as number);
res.status(code).send(data);
}
}
} catch(e) {
next(e);