-
Notifications
You must be signed in to change notification settings - Fork 0
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
Issue 5. Add Items to list #20
Conversation
…e item to database on list
Visit the preview URL for this PR (updated for commit 078f475): https://tcl-73-smart-shopping-list--pr20-ja-pc-feature-add-it-txa4cj02.web.app (expires Fri, 23 Feb 2024 23:47:09 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: 99eed22fcca8bd9874e77f7b7f7d1eeb554a1666 |
Hi @sillytsundere and @jaguilar89! I noticed I could submit an item when the input field and radio buttons were unselected. I could also submit an item with only a name and no date requirement, and also submit with no name and only a date requirement. When doing this I got the success alert. To overcome this I added a To enhance accessibility I also added an I could enter an item using the mouse and enter key! I am not sure if you want to enhance the accessibility more and add functionality for a user to select the radio buttons by using the tab and enter key also. Would definitely be extra challenge but might be fun! The Great work!! PS - I'm not sure if we should be seeing the items in Firebase DB with the extra functionality added for this issue. I couldn't see them, but I'm also still getting the hang of Firebase. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @jaguilar89 and @sillytsundere,
This looks so cool!
I added some comments on the changes I made on the branch, as well as a couple additional non-blocking suggestions that I didn't implement.
src/views/ManageList.jsx
Outdated
name="itemName" | ||
type="text" | ||
id="item" | ||
required |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added required so form field can't be left blank on submit
src/views/ManageList.jsx
Outdated
name="daysUntilNextPurchase" | ||
type="radio" | ||
id="soon" | ||
required |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added required so form field can't be left blank on submit
src/views/ManageList.jsx
Outdated
name="daysUntilNextPurchase" | ||
type="radio" | ||
id="kind-of-soon" | ||
required |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added required so form field can't be left blank on submit
src/views/ManageList.jsx
Outdated
onChange={handleChangeDate} | ||
name="daysUntilNextPurchase" | ||
type="radio" | ||
id="not-soon" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added id
attribute to match forHTML
attribute on <label>
for accessibility
src/views/ManageList.jsx
Outdated
onChange={handleChangeDate} | ||
name="daysUntilNextPurchase" | ||
type="radio" | ||
id="kind-of-soon" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added id
attribute to match forHTML
attribute on <label>
for accessibility
src/views/ManageList.jsx
Outdated
onChange={handleChangeDate} | ||
name="daysUntilNextPurchase" | ||
type="radio" | ||
id="soon" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added id
attribute to match forHTML
attribute on <label>
for accessibility
src/views/ManageList.jsx
Outdated
<li> | ||
<label htmlFor="soon"> Soon (7 days)</label> | ||
<input | ||
value={7} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider making this your default value, to enhance accessibility. This can be achieved by adding another attribute here. If you chose to do this, you'll also need to update the initial state value to be "7".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We initially leave this part of the form unselected to account for accidental form submissions where an item name would be provided but the first radio button would already be selected, before the user has a chance to select it on their own. Whereas if there is no default radio button value, the user would see an error message, asking them to select an option first. See below screenshot.
As an alternative, we added a clear "Please select option" instruction to make it clear that the user must make a selection before submitting the form. See below screenshot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@trushmi What do you think?
…e no longer necessary
Jose and I made more changes, we agree with the changes suggested and implemented by Rachel to make the items of the form required so as to prevent items with no name or next purchase date to be entered into the list. Also Jose refactored the code to eliminate the need for useState and refactored the multiple hooks into one handleSubmit hook. This also removes the const newItem, an unused variable, calling the await directly without saving it in a variable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall, but I think we can make a few improvements.
src/views/ManageList.jsx
Outdated
Hello from the <code>/manage-list</code> page! | ||
</p> | ||
<div> | ||
<form id="item-form" onSubmit={handleSubmit}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend moving this form to a separate component in case we use it in the future. For example, we can create a component called RadioInput. The component should use props to receive the options, like this:
const options = [{label: "Soon (7 days)", value: 7, id: "soon"}, {label: "Kind of soon (14 days)", value: 14, id:"kind-of-soon"}];
...
<RadioInput name="daysUntilNextPurchase" options={options}/>
and inside of the component we can use those props:
function RadioInput({name, options}) {
return (
<ul>
{options.map((option) => (
<li>
<label htmlFor={option.id}>{option.label}</label>
<input value={option.value} name={name}... >
</li>
)
)}
<ul/>
)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good suggestion. However, Paige and I think it's unnecessary for now simply because we don't think a radio button component will be needed in the future, based on the acceptance criteria of future issues. But, we can always keep this suggestion in mind in case it does become a necessary change in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sillytsundere @jaguilar89 looks good!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed and tested. Looks good to me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice job completing this one! I left a few thoughts: feel to make any small changes you want or just make note of any changes you want to make moving forward (you can definitely leave the custom validation + status stuff for the future) and get this merged in!
const handleSubmit = async (e) => { | ||
e.preventDefault(); | ||
|
||
const formData = new FormData(e.target); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool approach here using the FormData api in conjunction with default form/input functionality to access necessary data. You don't see this often in client-side React apps, but totally legit thing to do so that's cool to see.
src/views/ManageList.jsx
Outdated
alert('There was a problem'); | ||
} | ||
|
||
formRef.current.reset(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder whether this reset()
should be inside of the try
branch of the try ... catch ...
. If there is an error that means that the item wasn't saved, so we probably don't want to clear the form on people (in case they want to try again?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense, clearing a form after a successful submit is expected behavior, not clearing it would clearly indicate there was a problem. I added this change.
src/views/ManageList.jsx
Outdated
|
||
alert('Item saved successfully'); | ||
} catch (error) { | ||
alert('There was a problem'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't necessarily have to fully display the error
in this catch statement, but I do think we could make this error status more specific.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I modified the catch block to display a more detailed error message.
try {
...
} catch (error) {
alert(`There was a problem: ${error.message}`);
};
name="daysUntilNextPurchase" | ||
type="radio" | ||
id="soon" | ||
required |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I said this to the other group as well, but the built in HTML validations actually aren't as accessible as one would hope. So I think down the road we should build our own validation + status displaying logic.
src/views/ManageList.jsx
Outdated
import { useRef } from 'react'; | ||
|
||
export function ManageList({ listPath }) { | ||
const formRef = useRef(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the best practice recommendation by the React team is to declare this as const formRef = useRef(null)
if you are going to assign the reference to a DOM element. I'm honestly not sure the different null
vs undefined
makes in the initial declaration in reality, but I would still recommend doing it so that your code can be as consistent as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noted. I will add this change. Thanks!
…e for useRef, moved form reset into try block so it only resets upon successful submission
Description
These code changes enable users to add items to their shopping lists via a form on the ManageLists view. The form uses semantic html elements to adhere to accessibility standards.
Related Issue
Closes #5
Acceptance Criteria
UI-related tasks:
ManageList
view displays a form that allows them to enter the name of the item and select how soon they anticipate needing to buy it again. There should be 3 choices for this:label
element associated with itEnter
keyData-related tasks:
console.log
in theaddItem
function insrc/api/firebase.js
is replaced with a function that adds the new document to the Firestore database. That function will be imported from thefirebase/firestore
module.nextPurchasedDate
Type of Changes
enhancement
Updates
Before
After
Testing Steps / QA Criteria
git pull
git checkout ja-pc-feature-add-item
npm ci
npm run start
Navigate to Manage List page to view form
Enter item and when you will next purchase item into form fields, submit form, view alert informing item was successfully saved
Navigate to List page to view newly added item