Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/api/routes/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ router.get('/user/:id', async (req, res) => {

//Default params, user specific params, unaccessible params
let currentParams = 'username ProfilePicture';
const userOnlyParams = ['email', 'verificationCode'];
const userOnlyParams = ['email', 'verificationCode', 'saved'];
const bannedParams = ['password'];

//If the current user is not signed in or not the same user requesting data. Update boolean and return limited data.
Expand Down Expand Up @@ -315,8 +315,9 @@ router.post('/user/:id/pfp', (req, res) => {

// follow/unfollow a user
router.post('/user/:id/follow', async (req, res) => {
const { id } = req.params; // id of the user who wants to follow/unfollow someone
const { userIdToFollow } = req.body; // id of the user who is to be followed/unfollowed
//Id's are flipped for some reason
const { id } = req.params; // id of the user who is to be followed/unfollowed
const { userIdToFollow } = req.body; //id of the user who wants to follow/unfollow someone

if (!userIdToFollow) {
return res.status(400).send('User ID to follow/unfollow is required');
Expand Down
6 changes: 6 additions & 0 deletions src/web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ type AuthContextType = {
setSaved: React.Dispatch<React.SetStateAction<string[]>>;
following: FollowingType[];
setFollowing: React.Dispatch<React.SetStateAction<FollowingType[]>>;
followers: FollowingType[];
setFollowers: React.Dispatch<React.SetStateAction<FollowingType[]>>;
};

export const AuthContext = createContext<AuthContextType | undefined>(
Expand All @@ -97,6 +99,7 @@ function App() {
const [accessTokenC] = useCookies('accessToken', '');
const [refreshTokenC] = useCookies('refreshToken', '');
const [following, setFollowing] = useState<FollowingType[]>([]);
const [followers, setFollowers] = useState<FollowingType[]>([]);
const location = useLocation();

// Login users
Expand All @@ -122,6 +125,7 @@ function App() {
setProfilePicture(response.data.ProfilePicture);
setSaved(response.data.saved);
setFollowing(response.data.following);
setFollowers(response.data.followers);
})
.catch((error) => {
return error;
Expand Down Expand Up @@ -154,6 +158,7 @@ function App() {
ProfilePicture,
Verified,
following,
followers,
setAccessToken,
setRefreshToken,
setEmail,
Expand All @@ -164,6 +169,7 @@ function App() {
saved,
setSaved,
setFollowing,
setFollowers,
}}
>
<ScrollToTop />
Expand Down
22 changes: 19 additions & 3 deletions src/web/src/Components/profile/FollowerPopup.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useState, useContext } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
import { AuthContext } from '../../App';

interface FollowerPopupProps {
followerIds: string[];
onClose: () => void;
user: any;
setFollowingCount: React.Dispatch<React.SetStateAction<number>>;
}

const FollowerPopup: React.FC<FollowerPopupProps> = ({
followerIds,
onClose,
user,
setFollowingCount,
}) => {
const Auth = useContext(AuthContext);
const [followers, setFollowers] = useState<
{
id: string;
Expand All @@ -29,9 +33,19 @@ const FollowerPopup: React.FC<FollowerPopupProps> = ({
const response = await axios.post('/users/multiple', {
ids: followerIds,
});

let loggedInUserFollowingSet = Auth!.following;
if (Auth!.username == '') {
loggedInUserFollowingSet = [];
}
// console.log("My username: " + Auth!.username);
// console.log("My followers: " + loggedInUserFollowingSet);

const followersWithFollowingStatus = response.data.map(
(follower: any) => {
const isFollowing = user.following.includes(follower._id);
let isFollowing = loggedInUserFollowingSet.some(
(followed) => followed === follower._id,
);
return {
id: follower._id,
username: follower.username,
Expand All @@ -54,14 +68,16 @@ const FollowerPopup: React.FC<FollowerPopupProps> = ({
);
const follow = async (id: string) => {
try {
await axios.post(`/user/${id}/follow`, { userIdToFollow: user._id });
await axios.post(`/user/${id}/follow`, { userIdToFollow: Auth!._id });
setFollowers(
followers.map((follower) =>
follower.id === id
? { ...follower, isFollowing: true }
: follower,
),
);

window.location.reload();
} catch (error) {
console.error(error);
}
Expand Down
52 changes: 46 additions & 6 deletions src/web/src/Components/profile/FollowingPopup.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useState, useContext } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
import { AuthContext } from '../../App';

interface FollowingPopupProps {
following: string[];
onClose: () => void;
curruser: any;
setFollowingCount: React.Dispatch<React.SetStateAction<number>>;
}

const FollowingPopup: React.FC<FollowingPopupProps> = ({
following,
onClose,
curruser,
setFollowingCount,
}) => {
const Auth = useContext(AuthContext);
const [followingUsers, setFollowingUsers] = useState<
{
id: string;
Expand All @@ -29,12 +33,28 @@ const FollowingPopup: React.FC<FollowingPopupProps> = ({
const response = await axios.post('/users/multiple', {
ids: following,
});

//Array used to assign unfollow buttons to the homepage user's followers based on the actual person accessing the page.
let loggedInUserFollowingSet = Auth!.following;
if (Auth!.username == '') {
loggedInUserFollowingSet = [];
}
// console.log("My username: " + Auth!.username);
// console.log("My following: " + loggedInUserFollowingSet);

const users = response.data.map((user: any) => ({
id: user._id,
username: user.username,
ProfilePicture: user.ProfilePicture,
isFollowing: true,
isFollowing: loggedInUserFollowingSet.some(
(following) => following === user._id,
),
}));
// console.log("Their Following: ");
// users.forEach((user: any) => {
// console.log(user.id + " ");
// });

setFollowingUsers(users);
} catch (error) {
console.error(error);
Expand All @@ -49,16 +69,36 @@ const FollowingPopup: React.FC<FollowingPopupProps> = ({
const unfollow = async (id: string) => {
try {
await axios.post(`/user/${id}/follow`, {
userIdToFollow: curruser._id,
userIdToFollow: Auth!._id,
});
setFollowingUsers(
followingUsers.filter((follower) => follower.id !== id),
);
//Only remove follower entry from tab if on your own profile, otherwise remove the button boolean but not the person!
if (Auth!._id === curruser._id) {
setFollowingUsers(
followingUsers.filter((follower) => follower.id !== id),
);

//setFollowingCount(prevCount => prevCount - 1);
} else {
toggleFollow(id);
}
window.location.reload();
} catch (error) {
console.error(error);
}
};

//Flip the following bool from one state to another given the id for the follower.
const toggleFollow = (userId: string) => {
setFollowingUsers((prevUsers) =>
prevUsers.map(
(user) =>
user.id === userId
? { ...user, isFollowing: !user.isFollowing } // Toggle isFollowing
: user, // Keep other users unchanged
),
);
};

return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50 rounded-xl">
<div className="relative w-full max-w-sm mx-auto bg-white rounded-xl shadow-lg text-gray-800 overflow-hidden">
Expand Down
19 changes: 9 additions & 10 deletions src/web/src/Pages/user/ProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,9 @@ const ProfilePage = () => {
}
});

if (Auth?.username === user.username) {
setShowFollowerPopup(true);
setShowFollowingPopup(true);
}
//FIX!
//setShowFollowerPopup(true);
//setShowFollowingPopup(true);
};

const fileInputRef = useRef<HTMLInputElement>(null);
Expand Down Expand Up @@ -289,19 +288,17 @@ const ProfilePage = () => {
<p
className="mt-2 cursor-pointer"
onClick={() => {
if (Auth?.username === user.username) {
setShowFollowerPopup(true);
}
//Followers pop up for all
setShowFollowerPopup(true);
}}
>
{followerCount} followers
</p>
<p
className="mt-2 cursor-pointer"
onClick={() => {
if (Auth?.username === user.username) {
setShowFollowingPopup(true);
}
//Following pop up for all
setShowFollowingPopup(true);
}}
>
{followingCount} following
Expand Down Expand Up @@ -586,13 +583,15 @@ const ProfilePage = () => {
followerIds={Array.from(followers || [])}
onClose={() => setShowFollowerPopup(false)}
user={user}
setFollowingCount={setFollowingCount}
/>
)}
{showFollowingPopup && (
<FollowingPopup
following={Array.from(following || [])}
onClose={() => setShowFollowingPopup(false)}
curruser={user}
setFollowingCount={setFollowingCount}
/>
)}

Expand Down