Skip to content

Commit

Permalink
Merge pull request #39 from the-collab-lab/el-improve-list-nav
Browse files Browse the repository at this point in the history
Improve user navigation in the list and between lists
  • Loading branch information
eva-lng authored Sep 26, 2024
2 parents 98452a7 + 275ca7c commit 13baf18
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 148 deletions.
95 changes: 95 additions & 0 deletions src/components/AddItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { useState } from 'react';
import { addItem } from '../api';

export function AddItem({ data, listPath }) {
const [formNewItem, setFormNewItem] = useState({
name: '',
nextPurchase: 0,
});
const [messageItem, setMessageItem] = useState('');

const handleNewItemChange = (e) => {
const { name, value } = e.target;
setFormNewItem((prevForm) => {
return {
...prevForm,
[name]: value,
};
});
};

const handleNewItemSubmit = async (e) => {
e.preventDefault();
const { name, nextPurchase } = formNewItem;

if (!name || !nextPurchase) {
setMessageItem('Please fill out all fields');
return;
}
try {
const normalizedName = (name) => {
return name
.toLowerCase()
.replace(/[^\w\s]|_/g, '')
.replace(/\s+/g, '');
};

const itemExists = data.some(
(item) => normalizedName(item.name) === normalizedName(name),
);

if (itemExists) {
alert(`${normalizedName(name)} is already in the list`);
return;
}

await addItem(listPath, {
itemName: name,
daysUntilNextPurchase: nextPurchase,
});
alert(`${name} has been successfully added to the list`);
setFormNewItem({
name: '',
nextPurchase: 0,
});
} catch (error) {
console.log('Failed to add the item: ', error);
alert(`Failed to add ${name} to the list. Please try again!`);
}
};

return (
<>
<form onSubmit={handleNewItemSubmit}>
<label htmlFor="name">Item name</label>
<input
id="name"
type="text"
placeholder="Item"
value={formNewItem.name}
onChange={handleNewItemChange}
name="name"
required
/>

<label htmlFor="nextPurchase">When is your next purchase</label>
<select
name="nextPurchase"
id="nextPurchase"
onChange={handleNewItemChange}
value={formNewItem.nextPurchase}
required
>
<option value="">---</option>
<option value={7}>Soon</option>
<option value={14}>Kind of soon</option>
<option value={30}>Not soon</option>
</select>

<button>Add Item</button>

<p>{messageItem}</p>
</form>
</>
);
}
44 changes: 44 additions & 0 deletions src/components/AddList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { createList } from '../api/firebase';

export function AddList({ setListPath, userId, userEmail }) {
const [listName, setListName] = useState('');

const navigate = useNavigate();

const handleCreateListButton = async (e) => {
e.preventDefault();

try {
await createList(userId, userEmail, listName);
alert(`${listName} list was successfully created.`);

const createListPath = `${userId}/${listName}}`;
setListPath(createListPath);
navigate('/list');
} catch (error) {
console.error('error creating a list', error);
alert('Failed to create the list. Please try again!');
}
};

return (
<>
<form onSubmit={handleCreateListButton}>
<label htmlFor="listName">List Name:</label>
<input
type="text"
id="listName"
value={listName}
onChange={(e) => setListName(e.target.value)}
placeholder="Enter the name of your new list"
required
/>
<button type="submit" className="button">
Create list
</button>
</form>
</>
);
}
4 changes: 4 additions & 0 deletions src/components/SingleList.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import './SingleList.css';
import { useNavigate } from 'react-router-dom';

export function SingleList({ name, path, setListPath }) {
const navigate = useNavigate();

function handleClick() {
setListPath(path);
navigate('/list');
}

return (
Expand Down
47 changes: 6 additions & 41 deletions src/views/Home.jsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,12 @@
import './Home.css';
import { SingleList } from '../components';
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { createList } from '../api/firebase';
import { AddList } from '../components/AddList';
import { auth } from '../api/config.js';
import { SignInButton, useAuth } from '../api/useAuth';

export function Home({ data, setListPath, userId, userEmail }) {
const [listName, setListName] = useState('');
const [message, setMessage] = useState('');
const navigate = useNavigate();
const { user } = useAuth();

const handleCreateListButton = async (e) => {
e.preventDefault();
if (!listName) {
setMessage('Enter a list name');
return;
}

try {
await createList(userId, userEmail, listName);
setMessage('New list successfully created');

const createListPath = `${userId}/${listName}}`;
setListPath(createListPath);
navigate('/list');
} catch (error) {
console.error('error creating a list', error);
setMessage('Failed to create list. Please try again!');
}
};

return (
<div className="Home">
{!!user ? (
Expand All @@ -56,21 +31,11 @@ export function Home({ data, setListPath, userId, userEmail }) {
))}
</ul>
)}

<form onSubmit={handleCreateListButton}>
<label htmlFor="listName">List Name:</label>
<input
type="text"
id="listName"
value={listName}
onChange={(e) => setListName(e.target.value)}
placeholder="Enter the name of your new list"
/>
<button type="submit" className="button">
Create list
</button>
{message}
</form>
<AddList
setListPath={setListPath}
userId={userId}
userEmail={userEmail}
/>
</>
) : (
<>
Expand Down
33 changes: 15 additions & 18 deletions src/views/List.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { ListItem } from '../components';

import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { ListItem } from '../components';
import { AddItem } from '../components/AddItem';
import {
comparePurchaseUrgency,
updateItem,
deleteItem,
} from '../api/firebase';

import { Link } from 'react-router-dom';

export function List({ data, listPath, lists }) {
const [searchItem, setSearchItem] = useState('');
const [errorMsg, setErrorMsg] = useState('');

const [items, setItems] = useState([]);

const listTitle = listPath.split('/')[1];

useEffect(() => {
const fetchItems = async () => {
const sortedItems = await comparePurchaseUrgency(data);
Expand Down Expand Up @@ -55,18 +55,15 @@ export function List({ data, listPath, lists }) {
const handleDelete = async (itemId) => {
try {
await deleteItem(listPath, itemId);
setErrorMsg('');
} catch (error) {
console.error(error.message, error);
setErrorMsg('Failed to delete the item. Please try again!');
alert('Failed to delete the item. Please try again!');
}
};

return (
<>
<p>
Hello from the <code>/list</code> page!
</p>
<h2>{listTitle}</h2>
{lists.length === 0 && (
<p>
It looks like you don&apos;t have any shopping lists yet. Head to the{' '}
Expand All @@ -75,14 +72,15 @@ export function List({ data, listPath, lists }) {
</p>
)}
{lists.length > 0 && data.length === 0 && (
<p>
Your list is currently empty. To add items, visit{' '}
<Link to="/manage-list">manage list</Link> and start building your
shopping list!
</p>
<>
<AddItem data={data} listPath={listPath} />
<p>Your list is currently empty.</p>
</>
)}
{lists.length > 0 && data.length > 0 && (
<>
<AddItem data={data} listPath={listPath} />

<form onSubmit={handleSearch}>
<div>
<label htmlFor="search-item-in-list"> Search items:</label>
Expand All @@ -101,6 +99,7 @@ export function List({ data, listPath, lists }) {
)}
</div>
</form>

{searchItem ? (
<ul>
{filterItems.map((item) => (
Expand Down Expand Up @@ -136,8 +135,6 @@ export function List({ data, listPath, lists }) {
))}
</ul>
)}

{errorMsg && <p>{errorMsg}</p>}
</>
)}
</>
Expand Down
Loading

0 comments on commit 13baf18

Please sign in to comment.