diff --git a/public/grocerease-light.png b/public/grocerease-light.png
new file mode 100644
index 0000000..3311940
Binary files /dev/null and b/public/grocerease-light.png differ
diff --git a/public/grocerease.png b/public/grocerease.png
new file mode 100644
index 0000000..49783f8
Binary files /dev/null and b/public/grocerease.png differ
diff --git a/src/App.jsx b/src/App.jsx
index 2851fcc..dbcdfe9 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -6,6 +6,10 @@ import { useAuth, useShoppingListData, useShoppingLists } from './api';
import { useStateWithStorage } from './utils';
+import ProtectedRoutes from './utils/ProtectedRoutes';
+
+import Login from './views/Login';
+
export function App() {
/**
* This custom hook takes the path of a shopping list
@@ -45,24 +49,29 @@ export function App() {
return (
- }>
-
- }
- />
-
- }
- />
- }
- />
+ }>
+ }>
+
+ }
+ />
+
+ }
+ />
+
+ }
+ />
+
+ } path="/login" />
);
diff --git a/src/api/useAuth.jsx b/src/api/useAuth.jsx
index c8927c0..22dca1b 100644
--- a/src/api/useAuth.jsx
+++ b/src/api/useAuth.jsx
@@ -33,16 +33,33 @@ export const SignOutButton = () => (
* @see https://firebase.google.com/docs/auth/web/start#set_an_authentication_state_observer_and_get_user_data
*/
export const useAuth = () => {
- const [user, setUser] = useState(null);
+ const [user, setUser] = useState(() => {
+ const storedUser = localStorage.getItem('user');
+ return storedUser ? JSON.parse(storedUser) : null;
+ });
useEffect(() => {
- auth.onAuthStateChanged((user) => {
- setUser(user);
+ const unsubscribe = auth.onAuthStateChanged((user) => {
if (user) {
+ setUser(user);
+ localStorage.setItem('user', JSON.stringify(user));
addUserToDatabase(user);
+ } else {
+ setUser(null);
+ localStorage.removeItem('user');
}
});
+ return () => unsubscribe();
}, []);
- return { user };
+ const signIn = async () => {
+ await signInWithPopup(auth, new GoogleAuthProvider());
+ };
+
+ const signOut = async () => {
+ await auth.signOut();
+ localStorage.removeItem('user');
+ };
+
+ return { user, signIn, signOut };
};
diff --git a/src/utils/ProtectedRoutes.jsx b/src/utils/ProtectedRoutes.jsx
new file mode 100644
index 0000000..c78e76d
--- /dev/null
+++ b/src/utils/ProtectedRoutes.jsx
@@ -0,0 +1,9 @@
+import { Outlet, Navigate } from 'react-router-dom';
+import { useAuth } from '../api/useAuth';
+
+const ProtectedRoutes = ({}) => {
+ const { user } = useAuth();
+ const isAuthenticated = user || localStorage.getItem('user');
+ return isAuthenticated ? : ; // Redirect to login if not authenticated
+};
+export default ProtectedRoutes;
diff --git a/src/views/Login.jsx b/src/views/Login.jsx
new file mode 100644
index 0000000..f0fb585
--- /dev/null
+++ b/src/views/Login.jsx
@@ -0,0 +1,33 @@
+import { useAuth } from '../api/useAuth';
+import { useEffect } from 'react';
+import { useNavigate } from 'react-router-dom';
+
+function Login() {
+ const { user, signIn } = useAuth();
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ if (user) {
+ navigate('/');
+ }
+ }, [user]);
+
+ return (
+
+
+
+
+
+
+
+
+ );
+}
+
+export default Login;