Skip to content

Commit

Permalink
enable sending friend requests
Browse files Browse the repository at this point in the history
  • Loading branch information
annacai44 committed Jan 21, 2025
1 parent b9de66b commit 220e494
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import FriendRequests from './components/Account/Friends/FriendRequests';
import MyFriends from './components/Account/Friends/MyFriends';
import RatingHistory from './components/RatingHistory/RatingHistory';
import Comment from './components/Comment/Comment';
import SearchPage from './components/SearchPage/SearchPage';

// Toggle this to `true` in dev if you want to skip sign-in
const DEV_MODE = false;
Expand Down Expand Up @@ -63,6 +64,7 @@ function App() {
path="/submission"
element={isAuthenticated ? <Submission userName={user} /> : <Navigate to="/" />}
/>
<Route path="/search" element={user ? <SearchPage userUID={user.uid} /> : <Navigate to="/" />} />
<Route
path="/account"
element={
Expand Down
2 changes: 2 additions & 0 deletions src/components/NavigationBar/NavigationBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { BottomNavigation, BottomNavigationAction } from "@mui/material";
import AccountCircleIcon from "@mui/icons-material/AccountCircle";
import RestoreIcon from '@mui/icons-material/Restore';
import RateReviewIcon from '@mui/icons-material/RateReview';
import PersonSearchIcon from '@mui/icons-material/PersonSearch';
import { Link } from "react-router-dom";
import "./NavigationBar.css";

function NavigationBar() {
return (
<BottomNavigation className="nav-bar" showLabels>
<BottomNavigationAction label="Feed" icon={<RestoreIcon />} component={Link} to="/feed" />
<BottomNavigationAction label="Friends" icon={<PersonSearchIcon />} component={Link} to="/search" />
<BottomNavigationAction label="Post" icon={<RateReviewIcon />} component={Link} to="/submission" />
<BottomNavigationAction label="Profile" icon={<AccountCircleIcon />} component={Link} to="/account" />
</BottomNavigation>
Expand Down
11 changes: 9 additions & 2 deletions src/components/SearchPage/SearchPage.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
.search-page {
height: 100vh;
.search-content {
height: calc(100vh - 56px - 64px);
margin-top: 6rem;
}

.profile-pic {
width: 40px;
height: 40px;
margin-right: 10px;
}
79 changes: 71 additions & 8 deletions src/components/SearchPage/SearchPage.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,54 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import "./SearchPage.css";
import AppBar from '../AppBar/AppBar';
import NavigationBar from '../NavigationBar/NavigationBar';
import { Container, Box, TextField, List, ListItem, ListItemText, Button, InputAdornment } from '@mui/material';
import SearchIcon from '@mui/icons-material/Search';
import { db } from "../../utilities/firebase";
import { collection, getDocs, updateDoc, arrayUnion, getDoc, doc } from "firebase/firestore";
import Avatar from '@mui/material/Avatar';

const friendsDb = ["Anna", "Andrew", "Angela", "Anthony", "Ben", "Bella", "Chris", "Catherine", "Diana"];
async function getUsersFromDB() {
// get all the users from the database
const querySnapshot = await getDocs(collection(db, "users"));
const users = [];
querySnapshot.forEach((doc) => {
users.push({id: doc.id, ...doc.data()});
});
return users;
}

function SearchPage() {
function SearchPage({userUID}) {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const [users, setUsers] = useState([]);
// user information about current user (me)
const [me, setMe] = useState(null);

// useEffect runs every time the component is rendered
useEffect(() => {
async function fetchUsers() {
try {
const fetchedUsers = await getUsersFromDB();
setUsers(fetchedUsers);
} catch (error) {
console.error("Error fetching users: ", error);
}
}
fetchUsers();

async function fetchMe() {
try {
const meRef = doc(db, "users", userUID);
const res = await getDoc(meRef);

setMe(res.data());
} catch (error) {
console.error("Error fetching users: ", error);
}
}
fetchMe();
}, []);

const handleSearch = (event) => {
const value = event.target.value;
Expand All @@ -20,7 +59,7 @@ function SearchPage() {
return;
}

const filtered = friendsDb.filter(name => name.toLowerCase().includes(value.toLowerCase()))
const filtered = users.filter(user => user.displayName.toLowerCase().includes(value.toLowerCase()))
.sort((a, b) => {
if (a.toLowerCase().startsWith(value.toLowerCase())) return -1;
if (b.toLowerCase().startsWith(value.toLowerCase())) return 1;
Expand All @@ -30,10 +69,29 @@ function SearchPage() {
setResults(filtered);
};

async function sendFriendRequest (friend) {
try {
const meRef = doc(db, "users", userUID);

await updateDoc(meRef, {
friendRequests: arrayUnion(friend.id)
});

console.log(`Successfully added ${friend.id} to friend requests.`);

setMe((prevMe) => ({
...prevMe,
friendRequests: [...prevMe.friendRequests, friend.id],
}));
} catch (error) {
console.error('Error sending friend request:', error);
}
}

return (
<div>
<AppBar />
<Container className="search-page" maxWidth="sm">
<Container className="search-content" maxWidth="sm">
<Box my={4}>
<TextField
fullWidth
Expand All @@ -52,10 +110,15 @@ function SearchPage() {
}}
/>
<List>
{results.map((name, index) => (
{results.filter(stranger => stranger.displayName !== me.displayName).map((stranger, index) => (
<ListItem key={index} button>
<ListItemText primary={name} />
<Button variant="outlined">Request</Button>
<Avatar className="profile-pic" src={stranger.photoURL} />
<ListItemText primary={stranger.displayName} />
{me.friends.includes(stranger.id) ?
<Button variant="outlined">Following</Button> :
(me.friendRequests.includes(stranger.id) ?
<Button variant="outlined">Requested</Button> :
<Button variant="outlined" onClick={() => sendFriendRequest(stranger)}>Request</Button>)}
</ListItem>
))}
</List>
Expand Down
16 changes: 12 additions & 4 deletions src/utilities/createUserDocIfNotExists.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { doc, setDoc } from "firebase/firestore";
import { doc, setDoc, getDoc } from "firebase/firestore";
import { db } from "./firebase";

/**
Expand All @@ -10,6 +10,14 @@ export async function createUserDocIfNotExists(user) {
if (!user) return;

const userRef = doc(db, "users", user.uid);

// Check if the user doc already exists
const userSnapshot = await getDoc(userRef);

if (userSnapshot.exists()) {
console.log("User doc already exists. No need to overwrite fields.");
return;
}

// We "merge" so we don't overwrite any existing fields
await setDoc(
Expand All @@ -18,8 +26,8 @@ export async function createUserDocIfNotExists(user) {
displayName: user.displayName || null,
email: user.email || null,
photoURL: user.photoURL || null,
friends: [] // If doc already exists, it won't overwrite unless empty
},
{ merge: true }
friends: [], // If doc already exists, it won't overwrite unless empty
friendRequests: [], // If doc already exists, it won't overwrite unless empty
}
);
}

0 comments on commit 220e494

Please sign in to comment.