generated from the-collab-lab/smart-shopping-list
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: Allowing user to add items to shopping list (#22)
* adding a form layout to manage list * update item label tag Co-authored-by: Ross Clettenberg <[email protected]> * installed react-hot-toast and added toast for successful item add Co-authored-by: Ross Clettenberg <[email protected]> * modified addItem in firebase.js and WIP: parameters of call in ManageList Co-authored-by: Ross Clettenberg <[email protected]> * cleaning up form tags and adding select possiblity * adding the listPath prop to the ManageList component Co-authored-by: Ross Clettenberg <[email protected]> * making form controlled with state, adding the listPath info and controlling the state of form info * replaced console.log in addItem (firebase.js) with addDoc and updated toast to use toast.promise Co-authored-by: Ross Clettenberg <[email protected]> * chore: Add console logs and error logging in MAnageList.jsx. * chore: Add console log for listpath in ManageList.jsx * Added console log for adding item to list success. * change the when to buy options to a fieldset * adding aria-label to form submit button Co-authored-by: Ross Clettenberg <[email protected]> * refactor: Improve form submission by adding strings to radio button selection, removing redundant console logs, and fixing single quotes in ManageList.jsx Co-authored-by: Brianna <[email protected]> * feat: Improve ManageList component by setting daysUntilNextPurchase as key value pairs. This way the variable numbers can be changed at the top in the purchaseTimelines object. Co-authored-by: Brianna <[email protected]> * remoiving debug console.logs and resetting state or keeping during form success or error * refactor: removed unneeded setState calls in toast error func * fix: remove the unneeded parseInt in firebase.js * refactor: add validation for no empty items, added constants for timelines * refactor: added valid trim input util, added validation of text and radio input --------- Co-authored-by: Ross Clettenberg <[email protected]> Co-authored-by: RossaMania <[email protected]>
- Loading branch information
1 parent
df11ec1
commit 8aa6847
Showing
7 changed files
with
198 additions
and
14 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from "./dates"; | ||
export * from "./hooks"; | ||
export * from './dates'; | ||
export * from './hooks'; | ||
export * from './validateTrimmedString'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// makes sure the string passed into the function isn't an empty string | ||
export function validateTrimmedString(input) { | ||
const trimmedInput = input.trim(); | ||
|
||
if (trimmedInput.length === 0) { | ||
return null; | ||
} | ||
|
||
return trimmedInput; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,143 @@ | ||
export function ManageList() { | ||
import { useState } from 'react'; | ||
import { addItem } from '../api/firebase'; | ||
import { validateTrimmedString } from '../utils'; | ||
import toast, { Toaster } from 'react-hot-toast'; | ||
|
||
const SOON = 'soon'; | ||
const KIND_OF_SOON = 'kindOfSoon'; | ||
const NOT_SOON = 'notSoon'; | ||
|
||
const purchaseTimelines = { | ||
[SOON]: 7, | ||
[KIND_OF_SOON]: 14, | ||
[NOT_SOON]: 30, | ||
}; | ||
|
||
export function ManageList({ listPath }) { | ||
const [itemName, setItemName] = useState(''); | ||
const [itemNextPurchaseTimeline, setItemNextPurchaseTimeline] = | ||
useState(SOON); | ||
|
||
const handleItemNameTextChange = (e) => { | ||
setItemName(e.target.value); | ||
}; | ||
|
||
const handleNextPurchaseChange = (e) => { | ||
setItemNextPurchaseTimeline(e.target.value); | ||
}; | ||
|
||
const handleSubmit = async (e) => { | ||
e.preventDefault(); | ||
const trimmedItemName = validateTrimmedString(itemName); | ||
|
||
if (!trimmedItemName) { | ||
toast.error( | ||
'Item name cannot be empty or just spaces. Please enter a valid name.', | ||
); | ||
return; | ||
} | ||
|
||
if (!(itemNextPurchaseTimeline in purchaseTimelines)) { | ||
toast.error( | ||
'Selected purchase timeline is invalid. Please choose a valid option.', | ||
); | ||
return; | ||
} | ||
|
||
const daysUntilNextPurchase = purchaseTimelines[itemNextPurchaseTimeline]; | ||
|
||
try { | ||
await toast.promise( | ||
addItem(listPath, { | ||
itemName: trimmedItemName, | ||
daysUntilNextPurchase, | ||
}), | ||
{ | ||
pending: 'Adding item to list.', | ||
success: () => { | ||
setItemName(''); | ||
setItemNextPurchaseTimeline(SOON); | ||
return `${itemName} successfully added to your list!`; | ||
}, | ||
error: () => { | ||
return `${itemName} failed to add to your list. Please try again!`; | ||
}, | ||
}, | ||
); | ||
} catch (error) { | ||
console.error('Failed to add item:', error); | ||
} | ||
}; | ||
|
||
return ( | ||
<p> | ||
Hello from the <code>/manage-list</code> page! | ||
</p> | ||
<div> | ||
<p> | ||
Hello from the <code>/manage-list</code> page! | ||
</p> | ||
<form onSubmit={handleSubmit}> | ||
<label htmlFor="item-name"> | ||
Item: | ||
<input | ||
id="item-name" | ||
type="text" | ||
name="item" | ||
value={itemName} | ||
onChange={handleItemNameTextChange} | ||
required | ||
aria-label="Enter the item name" | ||
aria-required | ||
/> | ||
</label> | ||
<br /> | ||
<fieldset> | ||
<legend>When to buy:</legend> | ||
<label htmlFor={SOON}> | ||
<input | ||
type="radio" | ||
id={SOON} | ||
name="when-to-buy" | ||
value={SOON} | ||
required | ||
onChange={handleNextPurchaseChange} | ||
checked={itemNextPurchaseTimeline === SOON} | ||
aria-label={`Set buy to soon, within ${purchaseTimelines[SOON]} days`} | ||
/> | ||
Soon -- Within {purchaseTimelines[SOON]} days! | ||
</label> | ||
<br /> | ||
<label htmlFor={KIND_OF_SOON}> | ||
<input | ||
type="radio" | ||
id={KIND_OF_SOON} | ||
name="when-to-buy" | ||
value={KIND_OF_SOON} | ||
required | ||
onChange={handleNextPurchaseChange} | ||
checked={itemNextPurchaseTimeline === KIND_OF_SOON} | ||
aria-label={`Set buy to kind of soon, within ${purchaseTimelines[KIND_OF_SOON]} days`} | ||
/> | ||
Kind of soon -- Within {purchaseTimelines[KIND_OF_SOON]} days! | ||
</label> | ||
<br /> | ||
<label htmlFor={NOT_SOON}> | ||
<input | ||
type="radio" | ||
id={NOT_SOON} | ||
name="when-to-buy" | ||
value={NOT_SOON} | ||
required | ||
onChange={handleNextPurchaseChange} | ||
checked={itemNextPurchaseTimeline === NOT_SOON} | ||
aria-label={`Set buy to not soon, within ${purchaseTimelines[NOT_SOON]} days`} | ||
/> | ||
Not soon -- Within {purchaseTimelines[NOT_SOON]} days! | ||
</label> | ||
</fieldset> | ||
<button type="submit" aria-label="Add item to shopping list"> | ||
Submit Item | ||
</button> | ||
</form> | ||
<Toaster /> | ||
</div> | ||
); | ||
} |