Skip to content

Commit

Permalink
refac: jwt auth
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffreysaeteros committed Apr 9, 2024
1 parent c793125 commit de58201
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 74 deletions.
11 changes: 7 additions & 4 deletions front-end/src/ProtectedRoute.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
// ProtectedRoute.js
import React from 'react';
import { Navigate } from 'react-router-dom';
import { Navigate, useLocation } from 'react-router-dom';

const ProtectedRoute = ({ children, loggedInUser }) => {
if (!loggedInUser) {
return <Navigate to="/login" replace />;
const location = useLocation();
const token = localStorage.getItem('token');

if (!loggedInUser || !token) {
return <Navigate to="/login" state={{ from: location }} replace />;
}

return children;
};

export default ProtectedRoute;
export default ProtectedRoute;
11 changes: 8 additions & 3 deletions front-end/src/pages/Form/SignUpPage.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';

const SignUpPage = ({ setLoggedInUser, loggedInUser }) => {
const SignUpPage = ({ setLoggedInUser, loggedInUser, setRegisteredUser }) => {
const navigate = useNavigate();
const [formData, setFormData] = useState({
fullname: '',
Expand Down Expand Up @@ -36,10 +36,15 @@ const SignUpPage = ({ setLoggedInUser, loggedInUser }) => {
})
.then(data => {
console.log('User registered:', data);
setLoggedInUser(data); // update loggedInUser state in App.js
setLoggedInUser(data.user); // Update loggedInUser state with the user object
setRegisteredUser("Please login to continue.");
navigate('/mainHome');
})
.catch(error => console.error('Error registering user:', error));
.catch(error => {
console.error('Error registering user:', error);
// Display an error message to the user
alert('Error registering user. Please try again.');
});
};

// redirect to profile page if user is already logged in
Expand Down
9 changes: 7 additions & 2 deletions front-end/src/pages/Form/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import axios from 'axios';

const Login = ({ setLoggedInUser }) => {
const Login = ({ registeredUser, setLoggedInUser }) => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [emailError, setEmailError] = useState('');
Expand Down Expand Up @@ -37,7 +37,11 @@ const Login = ({ setLoggedInUser }) => {
email,
password,
});
const user = response.data;
const { user, token } = response.data;
localStorage.setItem("loggedInUser", JSON.stringify(user.id));
localStorage.setItem('token', token); // store token in local storage
// console.log("loggedInUser id: ", localStorage.getItem("loggedInUser"));
// console.log("login token: ", localStorage.getItem("token"));
setLoggedInUser(user);
navigate('/mainHome');
} catch (error) {
Expand All @@ -57,6 +61,7 @@ const Login = ({ setLoggedInUser }) => {
</div>
<br />
{loginError && <div className="errorLabel">{loginError}</div>}
{<div className="errorLabel">{registeredUser}</div>}
<div className='flex flex-col items-start justify-center'>
<input
value={email}
Expand Down
92 changes: 47 additions & 45 deletions front-end/src/pages/Form/profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,57 +13,59 @@ const ProfilePage = ({ loggedInUser, setLoggedInUser }) => {

useEffect(() => {
if (loggedInUser) {
fetch(`http://localhost:3001/users/${loggedInUser.id}`)
.then((response) => response.json())
.then((data) => {
setProfile(data);
})
.catch((error) => {
console.error("Error fetching user profile:", error);
});
const token = localStorage.getItem('token');
if (!token) {
// Token not found, redirect to login page
navigate('/login');
return;
}

// Fetch current reads books
fetch(`http://localhost:3001/users/${loggedInUser.id}/books/currentReads`)
.then((response) => response.json())
.then((data) => {
setCurrentReads(data);
})
.catch((error) => {
console.error("Error fetching current reads:", error);
});
const fetchUserProfile = async () => {
try {
const response = await fetch(`http://localhost:3001/users/${loggedInUser.id}`, {
headers: {
Authorization: token,
},
});
if (response.ok) {
const data = await response.json();
setProfile(data);
} else {
console.error('Error fetching user profile:', response.status);
}
} catch (error) {
console.error('Error fetching user profile:', error);
}
};

// Fetch want to read books
fetch(`http://localhost:3001/users/${loggedInUser.id}/books/WanttoRead`)
.then((response) => response.json())
.then((data) => {
setWantToRead(data);
})
.catch((error) => {
console.error("Error fetching want to read:", error);
});
const fetchBooks = async (endpoint, setBooks) => {
try {
const response = await fetch(`http://localhost:3001/users/${loggedInUser.id}/books/${endpoint}`, {
headers: {
'Authorization': `Bearer ${token}`
},
});
if (response.ok) {
const data = await response.json();
setBooks(data);
} else {
console.error(`Error fetching ${endpoint}:`, response.status);
}
} catch (error) {
console.error(`Error fetching ${endpoint}:`, error);
}
};

// Fetch past reads books
fetch(`http://localhost:3001/users/${loggedInUser.id}/books/PastReads`)
.then((response) => response.json())
.then((data) => {
setPastReads(data);
})
.catch((error) => {
console.error("Error fetching past reads:", error);
});
// Fetch favorite books
fetch(`http://localhost:3001/users/${loggedInUser.id}/books/favorites`)
.then((response) => response.json())
.then((data) => {
setFavorites(data);
})
.catch((error) => {
console.error("Error fetching past reads:", error);
});
fetchUserProfile();
fetchBooks('WanttoRead', setWantToRead);
fetchBooks('PastReads', setPastReads);
fetchBooks('favorites', setFavorites);
}
}, [loggedInUser]);
}, [loggedInUser, navigate]);

const handleLogout = () => {
localStorage.removeItem("loggedInUser");
localStorage.removeItem("token");
setLoggedInUser(null);
navigate("/");
};
Expand Down
49 changes: 29 additions & 20 deletions front-end/src/pages/mainHome.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,35 @@ import React, { useEffect, useState } from "react";
import Header from "../components/header";
import BookShelf from "../components/bookshelf";

const MainHome = () => {
const MainHome = ({ loggedInUser, setLoggedInUser }) => {
const [currentReads, setCurrentReads] = useState([]);
const [wantToRead, setWantToRead] = useState([]);
const [pastReads, setPastReads] = useState([]);
const [friendsReads, setFriendsReads] = useState([]);
const [topReads, setTopReads] = useState([]);
const [suggestions, setSuggestions] = useState([]);

// Retrieve the loggedInUser from localStorage
const [loggedInUser, setLoggedInUser] = useState(null);
// console.log(localStorage.getItem("loggedInUser"));
// console.log(localStorage.getItem("token"));

useEffect(() => {
const storedUser = JSON.parse(localStorage.getItem("loggedInUser"));
setLoggedInUser(storedUser);
}, []);
console.log("Logged in user:", loggedInUser);
const storedUserJSON = localStorage.getItem("loggedInUser");
// localStorage.setItem("loggedInUser", JSON.stringify(loggedInUser));
if (storedUserJSON && storedUserJSON !== "undefined" && !loggedInUser) {
const storedUser = JSON.parse(storedUserJSON);
setLoggedInUser(storedUser);
}
}, [loggedInUser]);


// console.log("Logged in user:", loggedInUser);

useEffect(() => {
// Define an async function to fetch books
const fetchBooks = async () => {
if (!loggedInUser) return; // return early if loggedInUser -> null
if (!loggedInUser) return; // Return early if loggedInUser is null

// Retrieve the token from local storage
const token = localStorage.getItem('token');

const urls = [
`http://localhost:3001/users/${loggedInUser.id}/books/currentReads`,
Expand All @@ -34,43 +42,44 @@ const MainHome = () => {
];

try {
// Map each URL to a fetch request and then pass all promises to Promise.all
const allRequests = urls.map((url) =>
fetch(url).then((res) => res.json())
fetch(url, {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
}).then((res) => res.json())
);

const [
currentReadsData,
wantToRead,
pastReads,
wantToReadData,
pastReadsData,
friendsReadsData,
topReadsData,
suggestionsData,
] = await Promise.all(allRequests);

// Update state with the fetched data
setCurrentReads(currentReadsData);
setWantToRead(wantToRead);
setPastReads(pastReads);
setWantToRead(wantToReadData);
setPastReads(pastReadsData);
setFriendsReads(friendsReadsData);
setTopReads(topReadsData);
setSuggestions(suggestionsData);

console.log("Current Reads:", currentReadsData[0]);
// Handle additional data similarly
} catch (error) {
console.error("Error fetching book data:", error);
}
};

// Call the async fetch function
if (loggedInUser) {
// Ensure there's a current user ID before fetching
fetchBooks();
}
}, [loggedInUser]);



return (
<div className="bg-goodread-white">
{loggedInUser ? (
Expand Down

0 comments on commit de58201

Please sign in to comment.