diff --git a/app/(auth)/signin.js b/app/(auth)/signin.js
index 58383fdf..fc20dbe7 100644
--- a/app/(auth)/signin.js
+++ b/app/(auth)/signin.js
@@ -33,6 +33,7 @@ export default function SignIn() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [forgotLoading, setForgotLoading] = useState(false);
+ const [loginLoading, setLoginLoading] = useState(false);
const { setCurrentUserId } = useAuthContext();
const { height } = useWindowDimensions();
@@ -62,6 +63,7 @@ export default function SignIn() {
}, [timeIntervalPassword]);
async function handleSignIn() {
+ setLoginLoading(true);
if (process.env.EXPO_PUBLIC_TEST_UID) {
// Only allow login as test user while using `yarn test` to reduce errors
setCurrentUserId(process.env.EXPO_PUBLIC_TEST_UID);
@@ -74,6 +76,7 @@ export default function SignIn() {
showDialog("Error", getErrorString(e));
}
}
+ setLoginLoading(false);
}
async function handleForgotPassword() {
@@ -204,6 +207,7 @@ export default function SignIn() {
onPress={handleSignIn}
buttonColor={themeColors.accent}
labelStyle={styles.buttonText}
+ loading={loginLoading}
>
Login
@@ -216,7 +220,7 @@ export default function SignIn() {
style={styles.button}
labelStyle={styles.buttonText}
>
- Sign Up
+ Sign up
diff --git a/app/(auth)/signup.js b/app/(auth)/signup.js
index 3fcef494..0287c6d4 100644
--- a/app/(auth)/signup.js
+++ b/app/(auth)/signup.js
@@ -36,11 +36,14 @@ export default function SignUp() {
const [password, setPassword] = useState("");
const [passwordCheck, setPasswordCheck] = useState("");
+ const [signUpLoading, setSignUpLoading] = useState(false);
+
const { showDialog, showSnackBar } = useAlertContext();
const { height } = useWindowDimensions();
async function handleSubmit() {
+ setSignUpLoading(true);
try {
if (password !== passwordCheck) {
throw "Passwords don't match";
@@ -77,6 +80,7 @@ export default function SignUp() {
console.log(e);
showDialog("Error", getErrorString(e));
}
+ setSignUpLoading(false);
}
const styles = StyleSheet.create({
@@ -186,6 +190,7 @@ export default function SignUp() {
onPress={handleSubmit}
buttonColor={themeColors.accent}
labelStyle={styles.buttonText}
+ loading={signUpLoading}
>
Submit
diff --git a/app/content/assignments/players.js b/app/content/assignments/players.js
index fe51c651..0ce34173 100644
--- a/app/content/assignments/players.js
+++ b/app/content/assignments/players.js
@@ -3,14 +3,7 @@ import { router, useLocalSearchParams, useNavigation } from "expo-router";
import { doc, getDoc, runTransaction, updateDoc } from "firebase/firestore";
import { useCallback, useEffect, useMemo, useState } from "react";
import { ScrollView, View } from "react-native";
-import {
- ActivityIndicator,
- Appbar,
- Button,
- Icon,
- List,
- Text,
-} from "react-native-paper";
+import { Appbar, Button, Icon, List, Text } from "react-native-paper";
import { SafeAreaView } from "react-native-safe-area-context";
import { once } from "underscore";
import { themeColors } from "~/Constants";
@@ -409,7 +402,7 @@ function Index() {
}}
mode="contained"
buttonColor={themeColors.accent}
- textColor="white"
+ textColor={themeColors.highlight}
disabled={
!assignmentList.some((assignment) => assignment.markedForDelete)
}
@@ -420,12 +413,9 @@ function Index() {
},
}}
onPress={handleDelete}
+ loading={loadingDelete}
>
- {loadingDelete ? (
-
- ) : (
- "Delete"
- )}
+ Delete
)}
diff --git a/app/content/profile/index.js b/app/content/profile/index.js
index 0dfc2737..e6764a80 100644
--- a/app/content/profile/index.js
+++ b/app/content/profile/index.js
@@ -20,7 +20,7 @@ import {
TouchableOpacity,
View,
} from "react-native";
-import { ActivityIndicator, Appbar, Switch } from "react-native-paper";
+import { ActivityIndicator, Appbar, Button, Switch } from "react-native-paper";
import { SafeAreaView } from "react-native-safe-area-context";
import { debounce } from "underscore";
import { themeColors } from "~/Constants";
@@ -267,11 +267,8 @@ function Index() {
},
saveChangesButton: {
backgroundColor: themeColors.accent,
- paddingHorizontal: 20,
- paddingVertical: 10,
- borderRadius: 20,
+ width: 100,
marginBottom: 20,
- width: 100, // Increase the width of the button
alignSelf: "center",
},
saveChangesButtonText: {
@@ -451,16 +448,17 @@ function Index() {
)}
{/* Save Button */}
-
- {updateLoading ? (
-
- ) : (
- Update
- )}
-
+ Update
+
{/* Sign Out Button */}
diff --git a/app/content/team/index.js b/app/content/team/index.js
index 5c41c6b7..f29d6529 100644
--- a/app/content/team/index.js
+++ b/app/content/team/index.js
@@ -82,6 +82,7 @@ function Index() {
const [resetDialogVisible, setResetDialogVisible] = useState(false);
const hideResetDialog = () => setResetDialogVisible(false);
+ const [resetLoading, setResetLoading] = useState(false);
const [newName, setNewName] = useState("");
@@ -222,18 +223,23 @@ function Index() {
content="Resetting the season will wipe all leaderboards"
visible={resetDialogVisible}
onHide={hideResetDialog}
- buttons={["Cancel", "Reset Season"]}
- buttonsFunctions={[
- hideResetDialog,
- async () => {
- try {
- await resetLeaderboards(currentTeamId);
- await invalidateMultipleKeys(queryClient, [["best_attempts"]]);
- hideResetDialog();
- } catch (e) {
- console.log("Error resetting season:", e);
- showDialog("Error", getErrorString(e));
- }
+ buttons={[
+ { children: "Cancel", pressHandler: hideResetDialog },
+ {
+ children: "Reset Season",
+ pressHandler: async () => {
+ setResetLoading(true);
+ try {
+ await resetLeaderboards(currentTeamId);
+ await invalidateMultipleKeys(queryClient, [["best_attempts"]]);
+ hideResetDialog();
+ } catch (e) {
+ console.log("Error resetting season:", e);
+ showDialog("Error", getErrorString(e));
+ }
+ setResetLoading(false);
+ },
+ loading: resetLoading,
},
]}
/>
diff --git a/app/content/team/users/[user]/index.js b/app/content/team/users/[user]/index.js
index a5c0ba64..4d934265 100644
--- a/app/content/team/users/[user]/index.js
+++ b/app/content/team/users/[user]/index.js
@@ -65,9 +65,11 @@ function Index() {
const [removeDialogVisible, setRemoveDialogVisible] = useState(false);
const hideRemoveDialog = () => setRemoveDialogVisible(false);
+ const [removeLoading, setRemoveLoading] = useState(false);
const [banDialogVisible, setBanDialogVisible] = useState(false);
const hideBanDialog = () => setBanDialogVisible(false);
+ const [banLoading, setBanLoading] = useState(false);
const { showDialog, showSnackBar } = useAlertContext();
@@ -307,23 +309,31 @@ function Index() {
content="All data will be lost when this user is removed."
visible={removeDialogVisible}
onHide={hideRemoveDialog}
- buttons={["Cancel", "Remove User"]}
- buttonsFunctions={[
- hideRemoveDialog,
- async () => {
- try {
- await removeUser(currentTeamId, userId);
- await queryClient.removeQueries(["userInfo", userId]);
- await invalidateMultipleKeys(queryClient, [
- ["userInfo"],
- ["best_attempts"],
- ]);
- navigation.goBack();
- } catch (e) {
- console.log("Error removing user:", e);
- hideRemoveDialog();
- showDialog("Error", getErrorString(e));
- }
+ buttons={[
+ {
+ children: "Cancel",
+ pressHandler: hideRemoveDialog,
+ },
+ {
+ children: "Remove User",
+ pressHandler: async () => {
+ setRemoveLoading(true);
+ try {
+ await removeUser(currentTeamId, userId);
+ await queryClient.removeQueries(["userInfo", userId]);
+ await invalidateMultipleKeys(queryClient, [
+ ["userInfo"],
+ ["best_attempts"],
+ ]);
+ navigation.goBack();
+ } catch (e) {
+ console.log("Error removing user:", e);
+ hideRemoveDialog();
+ showDialog("Error", getErrorString(e));
+ setRemoveLoading(false);
+ }
+ },
+ loading: removeLoading,
},
]}
/>
@@ -333,23 +343,28 @@ function Index() {
content="Banning this user will delete all their data and prevent them from joining the team again."
visible={banDialogVisible}
onHide={hideBanDialog}
- buttons={["Cancel", "Ban User"]}
- buttonsFunctions={[
- hideBanDialog,
- async () => {
- try {
- await blacklistUser(currentTeamId, userId, userInfo, userEmail);
- await queryClient.removeQueries(["userInfo", userId]);
- await invalidateMultipleKeys(queryClient, [
- ["userInfo"],
- ["best_attempts"],
- ]); //invalidate cache
- navigation.goBack();
- } catch (e) {
- console.log("Error banning user:", e);
- hideBanDialog();
- showDialog("Error", getErrorString(e));
- }
+ buttons={[
+ { children: "Cancel", pressHandler: hideBanDialog },
+ {
+ children: "Ban User",
+ pressHandler: async () => {
+ setBanLoading(true);
+ try {
+ await blacklistUser(currentTeamId, userId, userInfo, userEmail);
+ await queryClient.removeQueries(["userInfo", userId]);
+ await invalidateMultipleKeys(queryClient, [
+ ["userInfo"],
+ ["best_attempts"],
+ ]); //invalidate cache
+ navigation.goBack();
+ } catch (e) {
+ console.log("Error banning user:", e);
+ hideBanDialog();
+ showDialog("Error", getErrorString(e));
+ setBanLoading(false);
+ }
+ },
+ loading: banLoading,
},
]}
/>
diff --git a/app/segments/(team)/blacklist.js b/app/segments/(team)/blacklist.js
index d16eec3e..e4d54a6f 100644
--- a/app/segments/(team)/blacklist.js
+++ b/app/segments/(team)/blacklist.js
@@ -1,4 +1,5 @@
import { useQueryClient } from "@tanstack/react-query";
+import { useState } from "react";
import { ScrollView, View } from "react-native";
import { Button, List } from "react-native-paper";
import { themeColors } from "~/Constants";
@@ -21,6 +22,8 @@ function Blacklist() {
const queryClient = useQueryClient(); // also called here for updating name
+ const [unbanLoading, setUnbanLoading] = useState({});
+
const invalidateKeys = [["blacklist"]];
if (blacklistIsLoading) return ;
@@ -52,10 +55,13 @@ function Blacklist() {
>
diff --git a/app/segments/(team)/chooseTeam.js b/app/segments/(team)/chooseTeam.js
index 8b8b18e5..25c9e331 100644
--- a/app/segments/(team)/chooseTeam.js
+++ b/app/segments/(team)/chooseTeam.js
@@ -35,6 +35,9 @@ function ChooseTeam() {
} = useAuthContext();
const queryClient = useQueryClient();
+ const [buttonLoading, setButtonLoading] = useState(false);
+ const [signoutLoading, setSignoutLoading] = useState(false);
+
const { showDialog, showSnackBar } = useAlertContext();
const {
@@ -83,6 +86,7 @@ function ChooseTeam() {
];
async function handleSignOut() {
+ setSignoutLoading(true);
try {
await signoutFireBase(auth);
signOut();
@@ -90,6 +94,7 @@ function ChooseTeam() {
console.log(e);
showDialog("Error", getErrorString(e));
}
+ setSignoutLoading(false);
}
useEffect(() => {
@@ -187,7 +192,7 @@ function ChooseTeam() {
setLoading(false);
}}
loading={loading}
- textColor="white"
+ textColor={themeColors.highlight}
>
);
}
diff --git a/components/dialog.js b/components/dialog.js
index 463b5ee4..3efa4725 100644
--- a/components/dialog.js
+++ b/components/dialog.js
@@ -16,10 +16,9 @@ export default function DialogComponent({
content,
visible,
onHide,
- buttons = ["Ok"],
- buttonsFunctions = [() => onHide()],
+ buttons = [{ children: "Ok", pressHandler: () => onHide(), loading: false }], //should I also include style in here?
}) {
- const Buttons = buttons.map((item, index) => {
+ const Buttons = buttons.map((button, index) => {
let style;
let labelStyle;
if (index === 0) {
@@ -27,17 +26,18 @@ export default function DialogComponent({
labelStyle = { color: themeColors.accent };
} else {
style = { backgroundColor: themeColors.accent };
- labelStyle = { color: "white" };
+ labelStyle = { color: themeColors.highlight };
}
return (
- {item}
+ {button["children"]}
);
});