Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ho list page #36

Merged
merged 11 commits into from
Mar 31, 2024
34 changes: 20 additions & 14 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { useShoppingListData, useShoppingLists } from './api';

import { useStateWithStorage } from './utils';

import ProtectedRoutes from './utils/protectedRoutes';

export function App() {
/**
* This custom hook takes the path of a shopping list
Expand Down Expand Up @@ -58,20 +60,24 @@ export function App() {
}
// Pass userId and userEmail as props
/>
<Route
path="/list"
element={<List data={data} listPath={listPath} />}
/>
<Route
path="/manage-list"
element={
<ManageList
listPath={listPath}
userId={userId}
existingItems={data}
/>
}
/>
<Route element={<ProtectedRoutes />}>
<Route
path="/list"
element={<List data={data} listPath={listPath} />}
/>
</Route>
<Route element={<ProtectedRoutes />}>
<Route
path="/manage-list"
element={
<ManageList
listPath={listPath}
userId={userId}
existingItems={data}
/>
}
/>
</Route>
</Route>
</Routes>
</Router>
Expand Down
17 changes: 14 additions & 3 deletions src/api/useAuth.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import { addUserToDatabase } from './firebase.js';
export const SignInButton = () => (
<button
type="button"
onClick={() => signInWithRedirect(auth, new GoogleAuthProvider())}
onClick={() => {
signInWithRedirect(auth, new GoogleAuthProvider());
}}
>
Sign In
</button>
Expand All @@ -21,7 +23,14 @@ export const SignInButton = () => (
* A button that signs the user out of the app using Firebase Auth.
*/
export const SignOutButton = () => (
<button type="button" onClick={() => auth.signOut()}>
<button
type="button"
onClick={() => {
auth.signOut();
localStorage.clear();
window.location.reload();
}}
>
Sign Out
</button>
);
Expand All @@ -33,15 +42,17 @@ export const SignOutButton = () => (
*/
export const useAuth = () => {
const [user, setUser] = useState(null);
const [pending, setPending] = useState(true);

useEffect(() => {
auth.onAuthStateChanged((user) => {
setUser(user);
if (user) {
addUserToDatabase(user);
}
setPending(false);
});
}, []);

return { user };
return { user, pending };
};
41 changes: 29 additions & 12 deletions src/components/ListItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { updateItem, deleteItem } from '../api/firebase';
import { useState, useEffect } from 'react';
import { getDaysBetweenDates } from '../utils';
import { CgDanger } from 'react-icons/cg';
import Checkbox from '@mui/material/Checkbox';
import { FaTrashAlt } from 'react-icons/fa';
import { Button } from '@mui/material';

export function ListItem({ id, listPath, itemData, timeNow }) {
const [itemChecked, setItemChecked] = useState(false);
Expand All @@ -17,6 +20,7 @@ export function ListItem({ id, listPath, itemData, timeNow }) {
}
}
}, [id]);

const setItemPurchased = () => {
setItemChecked((prev) => !prev);
updateItem(listPath, id, itemData);
Expand Down Expand Up @@ -58,22 +62,22 @@ export function ListItem({ id, listPath, itemData, timeNow }) {
}
if (daysTillNextPurchase <= 7) {
return (
<span>
<span className="flex items-center gap-2">
--- <CgDanger className="soon" />
Soon
</span>
);
}
if (daysTillNextPurchase > 7 && daysTillNextPurchase <= 30) {
return (
<span>
<span className="flex items-center gap-2">
--- <CgDanger className="kind-of-soon" />
Kind of soon
</span>
);
} else {
return (
<span>
<span className="flex items-center gap-2">
--- <CgDanger className="not-soon" />
Not soon
</span>
Expand All @@ -82,18 +86,31 @@ export function ListItem({ id, listPath, itemData, timeNow }) {
};

return (
<li className="ListItem">
<label htmlFor={name}>
<input
name={name}
type="checkbox"
checked={itemChecked}
<li className="flex gap-10">
<label htmlFor={name} className="flex items-center gap-2">
<Checkbox
size="3"
name="name"
onChange={setItemPurchased}
checked={itemChecked}
/>
{name}{' '}
{getUrgencyIndicator(timeNow, dateNextPurchased, dateLastPurchased)}
<p className={`${itemChecked ? 'line-through text-white/50' : ''}`}>
{name}
</p>
{itemChecked ? (
<></>
) : (
getUrgencyIndicator(timeNow, dateNextPurchased, dateLastPurchased)
)}
</label>
<button onClick={handleDelete}>Delete item</button>
<Button
onClick={handleDelete}
className="flex gap-2 md:gap-3 items-center"
variant="contained"
>
<FaTrashAlt className="h-5 w-5 md:h-7 md:w-7" />
<span className="md:text-lg font-bold">Delete item</span>
</Button>
</li>
);
}
1 change: 1 addition & 0 deletions src/components/SingleList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import './SingleList.css';
export function SingleList({ name, path, setListPath }) {
function handleClick() {
setListPath(path);
localStorage.setItem('list', name);
}

return (
Expand Down
11 changes: 11 additions & 0 deletions src/utils/protectedRoutes.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import { Navigate, Outlet } from 'react-router-dom';
import { useAuth } from '../api';

export default function ProtectedRoutes() {
const { user, pending } = useAuth();
if (pending) {
return <p>Loading...Please wait....</p>;
}
return user ? <Outlet /> : <Navigate to="/" />;
}
3 changes: 3 additions & 0 deletions src/views/Layout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ export function Layout() {
)}
</header>
<main className="Layout-main">
<h1 className="my-3 text-center font-extrabold text-4xl">
{localStorage.getItem('list') || 'No list selected'}
</h1>
<Outlet />
</main>
<nav className="Nav">
Expand Down
57 changes: 30 additions & 27 deletions src/views/List.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom';
import { getDaysBetweenDates } from '../utils';
import { comparePurchaseUrgency } from '../api/firebase';
import { ListItem } from '../components/ListItem';
import Button from '@mui/material/Button';

export function List({ data, listPath }) {
const [searchInput, setSearchInput] = useState('');
Expand Down Expand Up @@ -55,7 +56,7 @@ export function List({ data, listPath }) {
};

return (
<>
<div className="mt-10 flex justify-center">
{data.length < 1 ? (
<div className="welcome-prompt">
<h2>Welcome to Your List!</h2>
Expand All @@ -68,33 +69,35 @@ export function List({ data, listPath }) {
</button>
</div>
) : (
<>
<p>
Hello from the <code>/list</code> page!
</p>
<form>
<label htmlFor="search">Search: </label>
<input
type="search"
id="search"
value={searchInput}
onChange={(e) => setSearchInput(e.target.value)}
/>
<button type="button" onClick={clearSearchInput}>
X
</button>
<div>
<form className="flex flex-col md:flex-row items-center gap-5">
<div>
<label htmlFor="search">Search: </label>
<input
type="search"
id="search"
value={searchInput}
onChange={(e) => setSearchInput(e.target.value)}
className="p-3 focus:outline-none"
/>
</div>
<Button onClick={clearSearchInput} variant="contained">
<span className="text-lg font-bold">Clear</span>
</Button>
</form>
{items.map((item) => (
<ListItem
key={item.id}
id={item.id}
listPath={listPath}
itemData={item}
timeNow={timeNow}
/>
))}
</>
<div className="mt-20 flex flex-col gap-5">
{items.map((item) => (
<ListItem
key={item.id}
id={item.id}
listPath={listPath}
itemData={item}
timeNow={timeNow}
/>
))}
</div>
</div>
)}
</>
</div>
);
}
Loading