Skip to content

Commit

Permalink
IWB-3: added waitlist functionality (#311)
Browse files Browse the repository at this point in the history
* added blacklist hook

* black list feature works

* some unused stuff removal

* waitlist seems to work

* simplified removeBlacklist.js

* pretty

* removed transaction and hope that it works

* fixed useBlackList.js hook firestore error, and made blacklist check functional

* added refresh spinner for chooseTeam.js

* updated invalidateKeys and fixed some styling

* updated faulty invalidateKeys lists

* kinda works lmao

* updated the invalidateKeys again

* added waitlistError to ErrorComponent

* minor comment change

Co-authored-by: Jake Gehrke <91503842+Gehrkej@users.noreply.github.com>

* changed console log wording in removeBlacklist

Co-authored-by: Jake Gehrke <91503842+Gehrkej@users.noreply.github.com>

* removed copied over comment

* updated tiny comment

Co-authored-by: Jake Gehrke <91503842+Gehrkej@users.noreply.github.com>

* removed redundant log

Co-authored-by: Jake Gehrke <91503842+Gehrkej@users.noreply.github.com>

* fix - added email to blacklist record

* fix - added assertion if pfp exists when removing a user

* fixed "invalid-argument"

* added key

* removed redundant remove user fix

* pretty

* pretty

* added missing state from merge

* simple fix

---------

Co-authored-by: Jake Gehrke <91503842+Gehrkej@users.noreply.github.com>
Co-authored-by: Jake Gehrke <gehrkej@oregonstate.edu>
  • Loading branch information
3 people committed Aug 15, 2024
1 parent 2589d27 commit ad07383
Show file tree
Hide file tree
Showing 10 changed files with 334 additions and 86 deletions.
3 changes: 3 additions & 0 deletions Utility.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ export function getIconByKey(key) {
}

export function getInitials(fullName) {
if (!fullName) {
return "?";
}
const nameParts = fullName.trim().split(/\s+/);
return nameParts.map((part) => part.charAt(0).toUpperCase()).join("");
}
Expand Down
12 changes: 1 addition & 11 deletions app/(auth)/signup.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,6 @@ export default function SignUp() {
await setDoc(doc(db, "users", userCredential.user.uid), {
email: email,
});
await setDoc(doc(db, "teams", "1", "users", userCredential.user.uid), {
name: name,
// hardcoded pfp string for now, add pfp upload to profile settings in future PR
pfp: "",
// hardcoded "player" role for now, add role selection to profile settings in future PR
role: "player",
uid: userCredential.user.uid,
assigned_data: [],
uniqueDrills: [],
});

try {
await sendEmailVerification(auth.currentUser);
Expand All @@ -80,7 +70,7 @@ export default function SignUp() {
}

setCurrentUserId(userCredential.user.uid);
setCurrentUserInfo(userCredential.user);
setCurrentUserInfo({ ...userCredential.user, displayName: name });

// console.log(userCredential.user);
} catch (e) {
Expand Down
14 changes: 11 additions & 3 deletions app/content/team/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,12 @@ function Index() {
/>
);
const foundUsers = Object.values(userInfo)
.filter((user) =>
user.name.toLowerCase().includes(searchQuery.toLowerCase()),
)
.filter((user) => {
if (!user.name) {
return true;
}
return user.name.toLowerCase().includes(searchQuery.toLowerCase());
})
.sort((user1, user2) => {
// Assign priorities based on conditions
const getPriority = (user) => {
Expand All @@ -136,6 +139,11 @@ function Index() {
return priority1 - priority2;
}

//doesn't softlock in case displayName is null for some reason
if (!user1.name) {
return -1;
}

// If priorities are the same, then sort alphabetically by name
return user1.name.localeCompare(user2.name);
});
Expand Down
209 changes: 138 additions & 71 deletions app/segments/(team)/chooseTeam.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import {
sendEmailVerification,
signOut as signoutFireBase,
} from "firebase/auth";
import { doc, setDoc } from "firebase/firestore";
import { useCallback, useEffect, useState } from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { RefreshControl, ScrollView, Text, View } from "react-native";
import { Button } from "react-native-paper";
import { SafeAreaView } from "react-native-safe-area-context";
Expand All @@ -16,13 +15,21 @@ import ErrorComponent from "~/components/errorComponent";
import Loading from "~/components/loading";
import { useAlertContext } from "~/context/Alert";
import { useAuthContext } from "~/context/Auth";
import { addToTeam } from "~/dbOperations/addToTeam";
import { addToWaitlist } from "~/dbOperations/addToWaitlist";
import { useBlackList } from "~/dbOperations/hooks/useBlackList";
import { useWaitlist } from "~/dbOperations/hooks/useWaitlist";
import { invalidateMultipleKeys } from "~/dbOperations/invalidateMultipleKeys";
import { auth, db } from "~/firebaseConfig";
import { auth } from "~/firebaseConfig";

function ChooseTeam() {
const { signOut, currentUserId, currentUserInfo, setCurrentUserId } =
useAuthContext();
const {
signOut,
currentUserId,
currentUserInfo,
setCurrentUserId,
currentTeamId,
} = useAuthContext();
const queryClient = useQueryClient();

const { showDialog, showSnackBar } = useAlertContext();
Expand All @@ -33,12 +40,32 @@ function ChooseTeam() {
isLoading: blacklistIsLoading,
} = useBlackList();

const invalidateKeys = [["blacklist"]];
const {
data: waitlist,
error: waitlistError,
isLoading: waitlistIsLoading,
} = useWaitlist();

const state = useMemo(() => {
if (blacklist && blacklist[currentUserId]) {
return "blacklist";
}
if (waitlist && waitlist[currentUserId]) {
return "waitlist";
}
return "neutral";
}, [blacklist, currentUserId, waitlist]); //blacklist, waitlist, invited, neutral

const [verified, setVerified] = useState(false);
const [refreshing, setRefreshing] = useState(false); //for Refresh Control
const [loading, setLoading] = useState(false); //for resend email button

const invalidateKeys = [
["blacklist"],
["waitlist"],
["userInfo", { userId: currentUserId }],
];

async function handleSignOut() {
try {
await signoutFireBase(auth);
Expand Down Expand Up @@ -88,12 +115,12 @@ function ChooseTeam() {
setRefreshing(false);
}, []);

if (blacklistIsLoading) {
if (blacklistIsLoading || waitlistIsLoading) {
return <Loading />;
}

if (blacklistError) {
return <ErrorComponent errorList={[blacklistError]} />;
if (blacklistError || waitlistError) {
return <ErrorComponent errorList={[blacklistError, waitlistError]} />;
}

return (
Expand All @@ -109,39 +136,79 @@ function ChooseTeam() {
}
contentContainerStyle={{ flex: 1, justifyContent: "center" }}
>
<View
style={{
justifyContent: "center",
alignItems: "center",
}}
>
{blacklist[currentUserId] ? (
<Text
{!verified ? (
<View
style={{
alignItems: "center",
justifyContent: "center",
}}
>
<Text>Waiting for email verification...</Text>
<Button
style={{
fontSize: 16,
textAlign: "center",
color: "gray",
backgroundColor: themeColors.accent,
borderRadius: 12,
marginTop: 20,
}}
onPress={async () => {
setLoading(true);
try {
await sendEmailVerification(auth.currentUser);
console.log("Verification Email Sent!");
showSnackBar("Verification Email Sent!");
} catch (e) {
console.log("Error sending verification email: ", e);
showDialog("Error", getErrorString(e));
}
setLoading(false);
}}
loading={loading}
textColor="white"
>
You've been banned from this team.
</Text>
) : verified ? (
<Text
style={{
color: themeColors.highlight,
fontSize: 18,
textAlign: "center",
}}
>
Resend Verification Email
</Text>
</Button>
</View>
) : state === "blacklist" ? (
<Text
style={{
fontSize: 16,
textAlign: "center",
color: "gray",
}}
>
You've been banned from this team.
</Text>
) : state === "waitlist" ? (
<Text
style={{
fontSize: 16,
textAlign: "center",
color: "gray",
}}
>
Your request to join the team has been received
</Text>
) : state === "invited" ? (
<View
style={{
alignItems: "center",
justifyContent: "center",
}}
>
<Button
onPress={async () => {
// Update Firestore document
await setDoc(doc(db, "teams", "1", "users", currentUserId), {
name: currentUserInfo["displayName"],
pfp: "",
role: "player",
uid: currentUserId,
assigned_data: [],
uniqueDrills: [],
});
//temporary, should be replaced with multiple team functionality
await addToTeam(currentTeamId, currentUserId, currentUserInfo);
setCurrentUserId(currentUserId);
await invalidateMultipleKeys(queryClient, [
["userInfo", { userId: currentUserId }],
]);
// Navigate to the next page
await invalidateMultipleKeys(queryClient, invalidateKeys);
router.replace("/");
}}
style={{
Expand All @@ -160,47 +227,47 @@ function ChooseTeam() {
Join Team
</Text>
</Button>
) : (
<View
</View>
) : (
<View
style={{
alignItems: "center",
justifyContent: "center",
}}
>
<Button
onPress={async () => {
await addToWaitlist(
currentTeamId,
currentUserId,
currentUserInfo,
);
await invalidateMultipleKeys(queryClient, invalidateKeys);
}}
style={{
alignItems: "center",
justifyContent: "center",
backgroundColor: themeColors.accent,
borderRadius: 12,
marginTop: 20,
}}
>
<Text>Waiting for email verification...</Text>
<Button
<Text
style={{
backgroundColor: themeColors.accent,
borderRadius: 12,
marginTop: 20,
}}
onPress={async () => {
setLoading(true);
try {
await sendEmailVerification(auth.currentUser);
console.log("Verification Email Sent!");
showSnackBar("Verification Email Sent!");
} catch (e) {
console.log("Error sending verification email: ", e);
showDialog("Error", getErrorString(e));
}
setLoading(false);
color: themeColors.highlight,
fontSize: 18,
textAlign: "center",
}}
loading={loading}
textColor="white"
>
<Text
style={{
color: themeColors.highlight,
fontSize: 18,
textAlign: "center",
}}
>
Resend Verification Email
</Text>
</Button>
</View>
)}
Request to Join Team
</Text>
</Button>
</View>
)}
<View
style={{
alignItems: "center",
justifyContent: "center",
}}
>
<Button
onPress={handleSignOut}
style={{
Expand Down
3 changes: 2 additions & 1 deletion app/segments/(team)/manageForeignRequests.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Appbar, SegmentedButtons } from "react-native-paper";
import { SafeAreaView } from "react-native-safe-area-context";
import { themeColors } from "~/Constants";
import Blacklist from "~/app/segments/(team)/blacklist";
import Waitlist from "~/app/segments/(team)/waitlist";
import Header from "~/components/header";

function ManageForeignRequests() {
Expand Down Expand Up @@ -38,7 +39,7 @@ function ManageForeignRequests() {
const tabComponent = useMemo(
() => ({
invites: <></>,
waitlist: <></>,
waitlist: <Waitlist />,
blacklist: <Blacklist />,
}),
[],
Expand Down
Loading

0 comments on commit ad07383

Please sign in to comment.