Skip to content

Commit

Permalink
merged with main
Browse files Browse the repository at this point in the history
  • Loading branch information
jaguilar89 committed Apr 5, 2024
2 parents e289a6d + 427e415 commit db9664c
Show file tree
Hide file tree
Showing 26 changed files with 1,685 additions and 2,695 deletions.
3,640 changes: 1,176 additions & 2,464 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
"@fortawesome/free-regular-svg-icons": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/themes": "^3.0.1",
"@the-collab-lab/shopping-list-utils": "^2.2.0",
"firebase": "^10.1.0",
"react": "^18.2.0",
"react-dark-mode-toggle-2": "^2.0.9",
"react-dom": "^18.2.0",
"react-router-dom": "^6.14.2",
"react-toastify": "^10.0.5"
Expand Down
28 changes: 27 additions & 1 deletion src/api/firebase.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
deleteDoc,
Timestamp,
increment,
arrayRemove,
} from 'firebase/firestore';
import { useEffect, useState } from 'react';
import { db } from './config';
Expand Down Expand Up @@ -44,7 +45,10 @@ export function useShoppingLists(userId, userEmail) {
const listRefs = docSnap.data().sharedLists;
const newData = listRefs.map((listRef) => {
// We keep the list's id and path so we can use them later.
return { name: listRef.id, path: listRef.path };
return {
name: listRef.id,
path: listRef.path,
};
});
setData(newData);
}
Expand Down Expand Up @@ -287,3 +291,25 @@ export async function getListOwnerDetails(userId, listName) {
throw error;
}
}

export async function deleteSingleList(userEmail, listPath) {
const userRef = doc(db, 'users', userEmail);
const listRef = doc(db, listPath);

const listDoc = await getDoc(listRef);
const userDoc = await getDoc(userRef);

if (listDoc.data().ownerID !== userDoc.data().uid) {
throw new Error("You can't delete this list because you are not the owner");
}

try {
await deleteDoc(listRef);
updateDoc(userRef, {
sharedLists: arrayRemove(listRef),
});
return { success: true, message: 'List successfully deleted' };
} catch (error) {
throw new Error(`Could not delete current list. An error: ${error}`);
}
}
11 changes: 8 additions & 3 deletions src/api/useAuth.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@ import { auth } from './config.js';
import { GoogleAuthProvider, signInWithRedirect } from 'firebase/auth';
import { addUserToDatabase } from './firebase.js';
import { Button } from '@radix-ui/themes';

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faSignIn, faSignOut } from '@fortawesome/free-solid-svg-icons';
/**
* A button that signs the user in using Google OAuth. When clicked,
* the button redirects the user to the Google OAuth sign-in page.
* After the user signs in, they are redirected back to the app.
*/
export const SignInButton = () => (
<Button
className="custom-button"
variant="solid"
type="button"
className="custom-button"
onClick={() => signInWithRedirect(auth, new GoogleAuthProvider())}
>
<FontAwesomeIcon icon={faSignIn} />
Sign In
</Button>
);
Expand All @@ -24,10 +27,12 @@ export const SignInButton = () => (
*/
export const SignOutButton = () => (
<Button
className="custom-button"
variant="solid"
type="button"
className="custom-button"
onClick={() => auth.signOut()}
>
<FontAwesomeIcon icon={faSignOut} />
Sign Out
</Button>
);
Expand Down
18 changes: 10 additions & 8 deletions src/components/AddItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { isInputEmpty, isItemDuplicate } from '../utils/itemValidator.js';
import { SignInAlert } from './ModalAlerts.jsx';
import { useAuth } from '../api/useAuth.jsx';
import '../custom-styles.css';
import { Box, Button } from '@radix-ui/themes';
import { RadioGroup } from '@radix-ui/themes';
import { Box, Button, TextField, RadioGroup } from '@radix-ui/themes';
import { toast } from 'react-toastify';

export function AddItem({ listPath, data }) {
Expand Down Expand Up @@ -48,12 +47,15 @@ export function AddItem({ listPath, data }) {
<form ref={formRef} onSubmit={handleSubmit}>
<div>
<label htmlFor="item">Item Name</label>
<input
name="itemName"
type="text"
id="item"
onChange={handleItemName}
/>
<Box maxWidth="22em" pb="2">
<TextField.Root
variant="classic"
radius="large"
name="itemName"
type="text"
id="item"
></TextField.Root>
</Box>
</div>

<div>
Expand Down
20 changes: 14 additions & 6 deletions src/components/ListItem.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,11 @@
.ListItem-label {
margin-left: 0.2em;
width: 100%;
display: flex;
justify-content: space-between;
}

.ListItem-badge {
display: flex;
margin: 0px 10px;
align-items: center;
margin: 0;
margin-bottom: 0.5em;
}

.ListItem-badge > span {
Expand All @@ -51,6 +48,17 @@
margin: auto;
font-size: 1.3em;
font-weight: bold;
text-decoration: underline;
text-underline-offset: 5px;
}

.ListItem-container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}

.ListItem-row {
display: flex;
align-items: center;
width: 100%;
}
37 changes: 25 additions & 12 deletions src/components/ListItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { Timestamp } from 'firebase/firestore';
import { Badge } from '@radix-ui/themes';
import { toast } from 'react-toastify';
import { DeleteItemConfirm } from './ModalAlerts';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faTrashCan } from '@fortawesome/free-regular-svg-icons';

export function ListItem({ listPath, item, name }) {
const [isChecked, setIsChecked] = useState(item.isChecked || false);
Expand Down Expand Up @@ -38,7 +40,7 @@ export function ListItem({ listPath, item, name }) {

setIsChecked(!isExpired);
}
}, [item]);
}, [item, listPath]);

const getPurchaseUrgency = (item) => {
const today = Timestamp.now();
Expand Down Expand Up @@ -84,22 +86,33 @@ export function ListItem({ listPath, item, name }) {

return (
<div className="ListItem">
<li>
<input
checked={isChecked}
onChange={handleChange}
type="checkbox"
id={item.id}
/>

<label className="ListItem-label" htmlFor={item.id}>
<p>{name}</p>
<li className="ListItem-container">
<div className="ListItem-row">
<input
checked={isChecked}
onChange={handleChange}
type="checkbox"
id={item.id}
/>
<label className="ListItem-label" htmlFor={item.id}>
<p>{name}</p>
</label>
<button
className="delete-btn"
aria-label={`Delete ${name}`}
onClick={handleDelete}
>
<FontAwesomeIcon className="delete-icon" icon={faTrashCan} />
</button>
</div>
<div className="ListItem-row">
{getUrgencyBadgeInfo && (
<p
className="ListItem-badge"
aria-describedby={`Item purchase urgency ${getUrgencyBadgeInfo.message}`}
>
<Badge
aria-describedby={`Item purchase urgency ${getUrgencyBadgeInfo.message}`}
radius="full"
size="3"
color={getUrgencyBadgeInfo.badgeColor}
Expand All @@ -108,7 +121,7 @@ export function ListItem({ listPath, item, name }) {
</Badge>
</p>
)}
</label>
</div>
<DeleteItemConfirm onDelete={handleDelete} name={name} />
</li>
</div>
Expand Down
8 changes: 8 additions & 0 deletions src/components/ListOwnerMessage.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.owner-message {
position: fixed;
width: min(72ch, 100%);
bottom: 5.18rem;
padding: 0.4em 0.4em;
margin: 0 auto;
background-color: white;
}
9 changes: 7 additions & 2 deletions src/components/ListOwnerMessage.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { useListOwnerDetails } from '../utils';
import './ListOwnerMessage.css';

export function ListOwnerMessage({ currentUserId, userIdFromPath, listName }) {
const sharedListOwner = useListOwnerDetails(userIdFromPath, listName);

if (currentUserId === userIdFromPath) {
return <p>You own this list.</p>;
return <p className="owner-message">You own this list.</p>;
} else if (sharedListOwner) {
return <p>This list belongs to {sharedListOwner.ownerName}.</p>;
return (
<p className="owner-message">
This list belongs to {sharedListOwner.ownerName}.
</p>
);
} else {
return null; // Handle the case where there's no owner information available
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/ModalAlerts.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ export function DeleteItemConfirm({ onDelete, name }) {
return (
<AlertDialog.Root>
<AlertDialog.Trigger>
<button aria-label={`Delete ${name}`}>
<FontAwesomeIcon icon={faTrashCan} />
<button className="delete-btn" aria-label={`Delete ${name}`}>
<FontAwesomeIcon className="delete-icon" icon={faTrashCan} />
Delete
</button>
</AlertDialog.Trigger>
Expand Down
31 changes: 31 additions & 0 deletions src/components/NotFoundPage.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.not-found-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
width: 100%;
}

.not-found-heading {
font-size: 4.5em;
margin-bottom: 0;
}

.not-found-page-nav-link {
--color-text: var(--color-cobalt-blue);
color: var(--color-text);
font-size: 1.4em;
flex: 0 1 auto;
line-height: 1;
padding: 0.8rem;
text-align: center;
text-underline-offset: 0.1em;
text-decoration: none;
opacity: 0.7;
}

.not-found-page-nav-link:hover {
opacity: 1;
text-decoration: underline;
}
18 changes: 14 additions & 4 deletions src/components/NotFoundPage.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { NavLink } from 'react-router-dom';

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faHouse } from '@fortawesome/free-solid-svg-icons';

import './NotFoundPage.css';

export default function NotFoundPage() {
return (
<div>
<h1>404</h1>
<div className="not-found-container">
<h1 className="not-found-heading">404</h1>
<p>Oops! The page you are looking for does not exist.</p>
<Link to="/">Go to Home Page</Link>
<NavLink to="/" className="not-found-page-nav-link">
<div>
<FontAwesomeIcon icon={faHouse} className="nav-icon" />
<div>Go to Home Page</div>
</div>
</NavLink>
</div>
);
}
Loading

0 comments on commit db9664c

Please sign in to comment.