diff --git a/client/src/AccountScreen.js b/client/src/AccountScreen.js index 0f34f10..b026264 100644 --- a/client/src/AccountScreen.js +++ b/client/src/AccountScreen.js @@ -4,9 +4,8 @@ import styles from './components/styles/AccountScreen.styles'; import buttonStyles from './components/common/button'; import { retrieveData, removeData } from './caching'; - export default function AccountScreen({ navigation }) { - const [usernameValid, setUsernameValid] = useState(null) + const [usernameValid, setUsernameValid] = useState(null); useEffect(() => { const fetchUsername = async () => { @@ -17,8 +16,8 @@ export default function AccountScreen({ navigation }) { console.error('Error retrieving username:', error); } }; - fetchUsername(); -},[]); + fetchUsername(); + }, []); const logout = async () => { try { diff --git a/client/src/DisplayRoute.js b/client/src/DisplayRoute.js index c981418..c94d6ff 100644 --- a/client/src/DisplayRoute.js +++ b/client/src/DisplayRoute.js @@ -9,7 +9,6 @@ import displayRouteStyles from './components/styles/DisplayRoute.styles'; import locationCircleIcon from './assets/location-circle.png'; - export default function DisplayRouteScreen({ navigation, route }) { // route is a prop passed by the navigator, hence why that is used instead of other variable names const { origin, destination, routeData, polylineCoordinates } = route.params; diff --git a/client/src/FriendsScreen.js b/client/src/FriendsScreen.js index 783e71b..ed947af 100644 --- a/client/src/FriendsScreen.js +++ b/client/src/FriendsScreen.js @@ -1,3 +1,4 @@ +/* eslint-disable no-use-before-define */ import React, { useState, useEffect } from 'react'; import { View, @@ -10,20 +11,78 @@ import { } from 'react-native'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; import styles from './components/styles/FriendsScreen.styles'; +import { retrieveData } from './caching'; + +// Not logged in message component +function NotLoggedInMessage() { + return ( + + + You are not logged in + + + Please login to access friends dashboard. + + + ); +} + +// Loading component +function LoadingIndicator() { + return ( + + Loading friends dashboard... + + ); +} export default function FriendsScreen() { + const [username, setUsername] = useState(''); // Username of the person sending the request + const [isLoading, setIsLoading] = useState(true); const [friendRequestName, setFriendName] = useState(''); const [pendingFriends, setPendingFriends] = useState([]); const [currentFriends, setCurrentFriends] = useState([]); const [sentFriends, setSentFriends] = useState([]); - // Commented for future use - // const [senderName, setSenderName] = useState(''); + useEffect(() => { + // eslint-disable-next-line no-use-before-define + fetchUserAndFriends(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const fetchUserAndFriends = async () => { + try { + const retrievedUsername = await retrieveData('username'); + setUsername(retrievedUsername || ''); - const senderName = 'Conor'; // Username of the person sending the request + if (retrievedUsername && retrievedUsername !== '') { + // Fetch the friend requests and friends list + await pollFriendRequests(retrievedUsername); + } - // friend_list - // pending_friends + setIsLoading(false); + } catch (error) { + console.error('Error fetching user data:', error); + setIsLoading(false); + } + }; // Function to send a friend request const sendFriendRequest = async () => { @@ -31,7 +90,7 @@ export default function FriendsScreen() { // send friend request name & username of the person sending friend request const payload = { receiver: friendRequestName, - sender: senderName, // username of the person sending friend request + sender: username, // username of the person sending friend request }; const baseUrl = @@ -68,13 +127,8 @@ export default function FriendsScreen() { } }; - const Poll = async () => { + const pollFriendRequests = async (senderName) => { try { - // send friend request name & username of the person sending friend request - // const payload = { - // sender: "Conor", // username of the person sending friend request - // }; - const baseUrl = Platform.OS === 'web' ? 'http://localhost:8000' @@ -116,23 +170,29 @@ export default function FriendsScreen() { // Poll for friend requests every 5 seconds useEffect(() => { + // Only set up polling if the user is logged in + if (!username || username === '') { + return () => {}; // Return empty cleanup function if not logged in + } + + // Initial poll + pollFriendRequests(username); + const intervalId = setInterval(() => { - Poll(); + pollFriendRequests(username); }, 5000); // Poll every 5 seconds // Cleanup function to clear the interval when the component unmounts return () => clearInterval(intervalId); - }, []); + }, [username]); // Re-run if username changes // Function to accept a friend request const processFriendRequest = async (friend, answer) => { - // setCurrentFriends([...currentFriends, friend]); - try { // send friend request name & username of the person sending friend request const payload = { requester: friend, - user: senderName, + user: username, answer, }; @@ -158,7 +218,9 @@ export default function FriendsScreen() { alert(serverMessage.message); setPendingFriends(pendingFriends.filter((name) => name !== friend)); - setCurrentFriends(currentFriends.filter((name) => name !== friend)); + if (answer) { + setCurrentFriends([...currentFriends, friend]); + } } else { // Log the raw response text for debugging const responseText = await response.text(); @@ -175,7 +237,7 @@ export default function FriendsScreen() { try { // send friend request name & username of the person sending friend request const payload = { - user: senderName, // username of the person removing friend + user: username, // username of the person removing friend friend, // friend to be removed }; @@ -217,7 +279,7 @@ export default function FriendsScreen() { try { // send friend request name & username of the person sending friend request const payload = { - user: senderName, // username of the person removing friend + user: username, // username of the person removing friend friend, // friend to be removed }; @@ -254,6 +316,17 @@ export default function FriendsScreen() { } }; + // If still loading, show loading indicator + if (isLoading) { + return ; + } + + // If not logged in (username is empty), show not logged in message + if (!username || username === '') { + return ; + } + + // Otherwise, show the normal friends dashboard return ( @@ -293,7 +366,6 @@ export default function FriendsScreen() { Pending Friend Requests Poll()} data={pendingFriends} keyExtractor={(item, index) => index.toString()} renderItem={({ item }) => ( diff --git a/client/src/LogIn.js b/client/src/LogIn.js index ee10cfb..1944710 100644 --- a/client/src/LogIn.js +++ b/client/src/LogIn.js @@ -10,7 +10,6 @@ import { import { handleLogin } from './utils/accountUtils'; import styles from './components/styles/Login.styles'; - export default function LoginScreen({ navigation }) { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); @@ -19,28 +18,28 @@ export default function LoginScreen({ navigation }) { return ( - setUsername(text)} - style={styles.TextInput} - onSubmitEditing={() => ref2.current.focus()} - /> - setPassword(text)} - secureTextEntry - style={styles.TextInput} - /> - handleLogin(username, password, navigation)} - color="#841584" - > - Log In - + setUsername(text)} + style={styles.TextInput} + onSubmitEditing={() => ref2.current.focus()} + /> + setPassword(text)} + secureTextEntry + style={styles.TextInput} + /> + handleLogin(username, password, navigation)} + color="#841584" + > + Log In + ); diff --git a/client/src/SustainabilityDashboard.js b/client/src/SustainabilityDashboard.js index f6203aa..3e8c825 100644 --- a/client/src/SustainabilityDashboard.js +++ b/client/src/SustainabilityDashboard.js @@ -118,24 +118,25 @@ const configureLineChartData = (yearEmissions) => { // Month mapping to full names const monthMapping = { - 1: 'Jan', - 2: 'Feb', - 3: 'Mar', - 4: 'Apr', - 5: 'May', - 6: 'Jun', - 7: 'Jul', - 8: 'Aug', - 9: 'Sep', - 10: 'Oct', - 11: 'Nov', - 12: 'Dec', + month_1: 'Jan', + month_2: 'Feb', + month_3: 'Mar', + month_4: 'Apr', + month_5: 'May', + month_6: 'Jun', + month_7: 'Jul', + month_8: 'Aug', + month_9: 'Sep', + month_10: 'Oct', + month_11: 'Nov', + month_12: 'Dec', }; - // Sort the months numerically - const sortedMonths = Object.keys(yearEmissions) - // eslint-disable-next-line prettier/prettier - .sort((a, b) => parseInt(a, 10) - parseInt(b, 10)); + // Sort the months numerically based on their suffix + const sortedMonths = Object.keys(yearEmissions).sort( + (a, b) => parseInt(a.split('_')[1], 10) - parseInt(b.split('_')[1], 10), + ); + return { labels: sortedMonths.map((month) => monthMapping[month]), datasets: [ @@ -165,7 +166,50 @@ const chartConfig = { }, }; +// Not logged in message component +function NotLoggedInMessage() { + return ( + + + You are not logged in + + + Please log in to view your sustainability dashboard and track your + progress. + + + ); +} + +// Loading component +function LoadingIndicator() { + return ( + + Loading dashboard... + + ); +} + export default function Dashboard() { + const [username, setUsername] = useState(''); + const [isLoading, setIsLoading] = useState(true); const [userSustainabilityScore, setUserSustainabilityScore] = useState(0); const [userSustainabilityImage, setUserSustainabilityImage] = useState(bald); // Default image const [leaderBoardData, setLeaderBoardData] = useState([]); @@ -187,10 +231,26 @@ export default function Dashboard() { useEffect(() => { // eslint-disable-next-line no-use-before-define - getSustainabilityStats(); + fetchUserAndStats(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + const fetchUserAndStats = async () => { + try { + const retrievedUsername = await retrieveData('username'); + setUsername(retrievedUsername || ''); + + if (retrievedUsername && retrievedUsername !== '') { + // eslint-disable-next-line no-use-before-define + await getSustainabilityStats(retrievedUsername); + } + setIsLoading(false); + } catch (error) { + console.error('Error fetching user data:', error); + setIsLoading(false); + } + }; + const updateGridItems = (rawDistances) => { const items = [ { @@ -240,16 +300,8 @@ export default function Dashboard() { ); }; - const getSustainabilityStats = async () => { + const getSustainabilityStats = async (senderName) => { try { - let senderName = await retrieveData('username'); - - console.log(senderName); - - if (senderName == null) { - senderName = 'test_user'; // Default name if not found - } - const baseUrl = Platform.OS === 'web' ? 'http://localhost:8000' @@ -288,8 +340,8 @@ export default function Dashboard() { // Format leaderboard data with icons const formattedLeaderboardData = Object.entries(friendsSusScores) - .map(([username, sustainabilityScore]) => ({ - name: username, + .map(([usernameParam, sustainabilityScore]) => ({ + name: usernameParam, sustainabilityScore: parseInt(sustainabilityScore, 10), icon: getIconForScore(parseInt(sustainabilityScore, 10)), })) @@ -346,6 +398,17 @@ export default function Dashboard() { ]).start(); }; + // If still loading, show loading indicator + if (isLoading) { + return ; + } + + // If not logged in (username is empty), show not logged in message + if (!username || username === '') { + return ; + } + + // Otherwise, render the full dashboard return (