Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ I suggest completing my [8 hour JavaScript course tutorial video](https://youtu.
### Academic Honesty

**DO NOT COPY FOR AN ASSIGNMENT** - Avoid plagiargism and adhere to the spirit of this [Academic Honesty Policy](https://www.freecodecamp.org/news/academic-honesty-policy/).

30,436 changes: 16,692 additions & 13,744 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-icons": "^4.2.0",
"react-scripts": "4.0.3",
"react-scripts": "^5.0.1",
"web-vitals": "^1.1.2"
},
"scripts": {
Expand All @@ -35,6 +35,5 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {}
}
}
45 changes: 42 additions & 3 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,53 @@
import Header from './Header';
import Content from './Content';
import Footer from './Footer';
import { useState } from 'react';


function App() {

// States needed by both Content and Footer components
const [items, setItems] = useState([
{
id: 1,
checked: true,
item: "One half pound bag of Cocoa Covered Almonds Unsalted"
},
{
id: 2,
checked: false,
item: "Item 2"
},
{
id: 3,
checked: false,
item: "Item 3"
}
]);

const handleCheck = (id) => {
const listItems = items.map((item) => item.id === id ? { ...item, checked: !item.checked } : item);
setItems(listItems);
localStorage.setItem('shoppinglist', JSON.stringify(listItems));
}

const handleDelete = (id) => {
const listItems = items.filter((item) => item.id !== id);
setItems(listItems);
localStorage.setItem('shoppinglist', JSON.stringify(listItems));
}

return (
<div className="App">
<Header />
<Content />
<Footer />
<Header title="Groceries List" />
<Content
items = {items}
handleCheck = {handleCheck}
handleDelete = {handleDelete}
/>
<Footer
length = {items.length}
/>
</div>
);
}
Expand Down
61 changes: 8 additions & 53 deletions src/Content.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,15 @@
import { useState } from 'react';
import { FaTrashAlt } from 'react-icons/fa';

const Content = () => {
const [items, setItems] = useState([
{
id: 1,
checked: true,
item: "One half pound bag of Cocoa Covered Almonds Unsalted"
},
{
id: 2,
checked: false,
item: "Item 2"
},
{
id: 3,
checked: false,
item: "Item 3"
}
]);

const handleCheck = (id) => {
const listItems = items.map((item) => item.id === id ? { ...item, checked: !item.checked } : item);
setItems(listItems);
localStorage.setItem('shoppinglist', JSON.stringify(listItems));
}

const handleDelete = (id) => {
const listItems = items.filter((item) => item.id !== id);
setItems(listItems);
localStorage.setItem('shoppinglist', JSON.stringify(listItems));
}
import ItemList from "./ItemList"

const Content = ({items, handleCheck, handleDelete}) => {

return (
<main>
{items.length ? (
<ul>
{items.map((item) => (
<li className="item" key={item.id}>
<input
type="checkbox"
onChange={() => handleCheck(item.id)}
checked={item.checked}
/>
<label
style={(item.checked) ? { textDecoration: 'line-through' } : null}
onDoubleClick={() => handleCheck(item.id)}
>{item.item}</label>
<FaTrashAlt
onClick={() => handleDelete(item.id)}
role="button"
tabIndex="0"
/>
</li>
))}
</ul>
<ItemList
items = {items}
handleCheck = {handleCheck}
handleDelete = {handleDelete}
/>
) : (
<p style={{ marginTop: '2rem' }}>Your list is empty.</p>
)}
Expand Down
5 changes: 2 additions & 3 deletions src/Footer.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
const Footer = () => {
const today = new Date();
const Footer = ({length}) => {

return (
<footer>
<p>Copyright &copy; {today.getFullYear()}</p>
<p>{length} List {length === 1 ? "Item" : "Items"}</p>
</footer>
)
}
Expand Down
12 changes: 10 additions & 2 deletions src/Header.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
const Header = () => {
const Header = ( { title } ) => {

return (
<header>
<h1>Groceries List</h1>
<h1>{title}</h1>
</header>
)
}

// Default props - let us values for props expedcted in component. If not provided, default vaue takes over instead of error
// Good way to spec component and not receinvg data from API or local storage
Header.defaultProps = {
title : "Default List"
}



export default Header;
19 changes: 19 additions & 0 deletions src/ItemList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import LineItem from "./LineItem";

const ItemList = ({items, handleCheck, handleDelete}) => {
return (
// to display items in list in js, recommended to use .map() method
<ul>
{items.map((item) => (
<LineItem
key = {item.id}
item = {item}
handleCheck = {handleCheck}
handleDelete = {handleDelete}
/>
))}
</ul>
);
}

export default ItemList;
26 changes: 26 additions & 0 deletions src/LineItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { FaTrashAlt } from 'react-icons/fa';

const LineItem = ({item, handleCheck, handleDelete}) => {
return (
// Each list item in react MUST have a key - helps react know which items changed, added or removed
<li className="item" key={item.id}>
<input
type="checkbox"
onChange={() => handleCheck(item.id)} // with a checkbox we need a onChange event. To pass params we use anonlymous func {() => func(params)}
checked={item.checked}
/>
<label
style={(item.checked) ? { textDecoration: 'line-through' } : null}
onDoubleClick={() => handleCheck(item.id)}
>{item.item}</label>
<FaTrashAlt
onClick={() => handleDelete(item.id)}
role="button"
tabIndex="0"
aria-label={`Delete ${item.item}`} // used for screen readers
/>
</li>
);
}

export default LineItem;
2 changes: 1 addition & 1 deletion src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ main {
display: flex;
flex-direction: column;
flex-grow: 1;
justify-content: center;
justify-content: flex-start;
align-items: center;
overflow-y: auto;
}
Expand Down