Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

33 create the send invite component #128

Merged
merged 4 commits into from
May 30, 2024
Merged
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
2 changes: 1 addition & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function App() {
<Route
path="/groups/:groupId"
element={<IndividualGroupPage LoggedInUser={user} />}
/>{" "}
/>
{/* added route for individual group page */}
<Route
path="/items"
Expand Down
163 changes: 163 additions & 0 deletions frontend/src/components/SendInvite.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import React, { useState, useEffect } from "react";
import {
Button,
Popover,
PopoverTrigger,
PopoverContent,
PopoverHeader,
PopoverBody,
PopoverFooter,
PopoverCloseButton,
PopoverArrow,
} from "@chakra-ui/react";
import { IUser } from "../../../backend/models/userSchema";

interface Props {
groupId: string | undefined;
friends: IUser[];
members: IUser[];
}

const SendInviteToGroup: React.FC<Props> = ({ groupId, friends, members }) => {
// Create a set of member IDs for efficient lookup const memberIds = new Set(members.map(member => member._id));
const memberIds = new Set(members.map((member) => member._id));
// Initialize the friends state with the filtered friends prop
const [friendsNotInGroup, setFriendsNotInGroup] = useState<IUser[]>(() =>
friends.filter((friend) => !memberIds.has(friend._id)),
);

useEffect(() => {
// This effect runs when friends or members prop changes
const memberIds = new Set(members.map((member) => member._id));
setFriendsNotInGroup(
friends.filter((friend) => !memberIds.has(friend._id)),
);
}, [friends, members]);

// Function to handle button click and log members to the console
const handleLogMembers = () => {
console.log("friends:", friendsNotInGroup);
console.log("friend Users:", friends);
};
const addToGroup = async (friendId: string, groupId: string | undefined) => {
try {
const res1 = await fetch(`http://localhost:3001/groups/${groupId}`);

const res = await fetch(`http://localhost:3001/users/${friendId}`);
let friend;
let group;
if (res.ok && res1.ok) {
friend = await res.json();
group = await res1.json();
if (!group.members.includes(friendId)) {
group.members.push(friendId);
console.log("Pushed friend ID to group's member list");
const updatedRes1 = await fetch(
`http://localhost:3001/groups/${groupId}`,
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ members: group.members }),
},
);
if (updatedRes1.ok) {
console.log("Friend added to group's member list successfully");
} else {
console.error("Failed to update group");
}
}
if (!friend.groups.includes(groupId)) {
friend.groups.push(groupId);
console.log("Pushed to list");

const updatedRes = await fetch(
`http://localhost:3001/users/${friendId}`,
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ groups: friend.groups }),
},
);
if (updatedRes.ok) {
console.log("Friend added to group successfully");
} else {
console.error("Failed to update user");
}
} else {
console.log("Friend is already in group");
}
} else {
console.log("Group not Found");
}
} catch (error) {
console.error("Error adding friend:", error);
}
};

return (
<div>
<Popover>
<PopoverTrigger>
<Button
bg="teal"
color="white"
marginRight={{ md: "10px" }}
mb={{ base: 2, md: 0 }}
alignSelf={{ base: "flex-end", md: "center" }}
onClick={handleLogMembers}
_hover={{
bg: "var(--col-tertiary)",
color: "var(--col-dark)",
}}
>
Send Invite
</Button>
</PopoverTrigger>
<PopoverContent
bg="var(--col-bright)"
color="var(--col-dark)"
border="2px"
borderColor="var(--col-dark)"
>
<PopoverArrow />
<PopoverCloseButton />
<PopoverHeader fontWeight="bold">Friends not in this Group</PopoverHeader>
<PopoverBody>
{friendsNotInGroup.length > 0 ? (
<ul>
{friendsNotInGroup.map((friend) => (
<li
key={friend._id.toString()}
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
padding: "5px",
}}
>
<span>{friend.username}</span>
<Button
size="sm"
onClick={() => addToGroup(friend._id.toString(), groupId)}
>
Add to Group
</Button>
</li>
))}
</ul>
) : (
<p>No friends to add</p>
)}
</PopoverBody>
<PopoverFooter></PopoverFooter>
</PopoverContent>
</Popover>
</div>
);
};

export default SendInviteToGroup;
56 changes: 45 additions & 11 deletions frontend/src/pages/IndividualGroupPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { IUser } from "../../../backend/models/userSchema";
import BasketComp, { Basket } from "../components/Basket";
import Editgroup from "../components/EditGroup";
import NewBasketOptions from "../components/NewBasketOptions";
import SendInviteToGroup from "../components/SendInvite";

type Props = {
LoggedInUser: IUser | null;
Expand All @@ -30,8 +31,45 @@ const IndividualGroupPage: React.FC<Props> = ({ LoggedInUser }) => {
const [group, setGroup] = useState<IGroup | null>(null);
const [loading, setLoading] = useState(true);
const [members, setMembers] = useState<IUser[]>([]);
const [friends, setFriends] = useState<IUser[]>([]);
const [baskets, setBaskets] = useState<Basket[]>([]);
const navigate = useNavigate();
console.log(LoggedInUser);
console.log(friends);

const fetchFriends = async (friendIds: string[]) => {
try {
const fetchedFriends = await Promise.all(
friendIds.map(async (friendId) => {
const res = await fetch(`http://localhost:3001/users/${friendId}`);
if (res.ok) {
return res.json();
} else {
throw new Error(`Failed to fetch friends: ${res.statusText}`);
}
}),
);
setFriends(fetchedFriends);
} catch (err) {
console.error(err);
}
};

const fetchUsersFriends = async () => {
try {
const fetchedUser = await fetch(
`http://localhost:3001/users/${LoggedInUser?._id}`,
);
if (fetchedUser.ok) {
const data = await fetchedUser.json();
fetchFriends(data.friends);
} else {
throw new Error(`Failed to fetch User: ${fetchedUser.statusText}`);
}
} catch (err) {
console.error(err);
}
};

const fetchGroup = async () => {
try {
Expand All @@ -41,6 +79,7 @@ const IndividualGroupPage: React.FC<Props> = ({ LoggedInUser }) => {
if (fetchedGroup.ok) {
const data = await fetchedGroup.json();
setGroup(data);

fetchMembers(data.members);
fetchBaskets(data.baskets);
setLoading(false);
Expand Down Expand Up @@ -90,6 +129,7 @@ const IndividualGroupPage: React.FC<Props> = ({ LoggedInUser }) => {

useEffect(() => {
fetchGroup();
fetchUsersFriends();
}, [groupId]);

return (
Expand Down Expand Up @@ -123,17 +163,11 @@ const IndividualGroupPage: React.FC<Props> = ({ LoggedInUser }) => {
flexDirection={{ base: "column", md: "row" }}
mt={{ base: 4, md: 0 }}
>
<Button
onClick={() => console.log("Send Invite clicked")}
bg="teal"
color="white"
_hover={{ bg: "teal" }}
marginRight={{ md: "10px" }}
mb={{ base: 2, md: 0 }}
alignSelf={{ base: "flex-end", md: "center" }}
>
Send Invite
</Button>
<SendInviteToGroup
groupId={groupId}
friends={friends}
members={members}
></SendInviteToGroup>
<InputGroup width={{ base: "100%", md: "300px" }}>
<InputLeftElement pointerEvents="none" children={<IoSearch />} />
<Input
Expand Down
Loading