Skip to content

Myrthe Dullaart #116

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

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
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
20 changes: 0 additions & 20 deletions .eslintrc.cjs

This file was deleted.

Binary file added component-tree.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 9 additions & 34 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,19 @@
import './styles/reset.css'
import './styles/index.css'

import initialStoreItems from './store-items'
import Header from './components/header/Header'
import MainComponent from './components/main/MainComponent'
import Footer from './components/footer/Footer'
import { useState } from 'react'

export default function App() {
const [cartItem, setCartItem] = useState([])

return (
<>
<header id="store">
<h1>Greengrocers</h1>
<ul className="item-list store--item-list">
</ul>
</header>
<main id="cart">
<h2>Your Cart</h2>
<div className="cart--item-list-container">
<ul className="item-list cart--item-list">
</ul>
</div>
<div className="total-section">
<div>
<h3>Total</h3>
</div>
<div>
<span className="total-number">£0.00</span>
</div>
</div>
</main>
<div>
Icons made by
<a
href="https://www.flaticon.com/authors/icongeek26"
title="Icongeek26"
>
Icongeek26
</a>
from
<a href="https://www.flaticon.com/" title="Flaticon">
www.flaticon.com
</a>
</div>
<Header setCartItem={setCartItem} cartItem={cartItem}/>
<MainComponent cartItem={cartItem} setCartItem={setCartItem}/>
<Footer />
</>
)
}
19 changes: 19 additions & 0 deletions src/components/footer/Footer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function Footer() {
return (
<div>
Icons made by
<a
href="https://www.flaticon.com/authors/icongeek26"
title="Icongeek26"
>
Icongeek26
</a>
from
<a href="https://www.flaticon.com/" title="Flaticon">
www.flaticon.com
</a>
</div>
)
}

export default Footer
22 changes: 22 additions & 0 deletions src/components/header/Filter.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function Filter({ storeItems, setFilteredItems}) {
function filterProducts(e) {
if(e.target.value === 'default') {
setFilteredItems(storeItems)
} else {
setFilteredItems(storeItems.filter((i) => i.type === e.target.value))
}
}

return (
<div>
<label htmlFor="filter">Filter </label>
<select name="filter" id="filter" onChange={filterProducts}>
<option value="default">Select type</option>
<option value="vegetable">Vegetable</option>
<option value="fruit">Fruit</option>
</select>
</div>
)
}

export default Filter
32 changes: 32 additions & 0 deletions src/components/header/Header.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Filter from './Filter'
import StoreItemUl from './StoreItemUl'
import { useState } from 'react'
import initialStoreItems from '../../store-items'
import Sort from './Sort'

function Header({ setCartItem, cartItem}) {
const [storeItems] = useState(initialStoreItems)
const [sortedItems, setSortedItems] = useState('')
const [filteredItems, setFilteredItems] = useState(storeItems)

if (sortedItems === "alphabetically") {
filteredItems.sort((a, b) => {
return a.name.localeCompare(b.name)
})
} else if (sortedItems === 'price') {
filteredItems.sort((a, b) => {
return a.price - b.price
})
}

return (
<header id="store">
<h1>Greengrocers</h1>
<Filter setFilteredItems={setFilteredItems} storeItems={storeItems}/>
<Sort filteredItems={filteredItems} setSortedItems={setSortedItems}/>
<StoreItemUl setCartItem={setCartItem} cartItem={cartItem} filteredItems={filteredItems}/>
</header>
)
}

export default Header
18 changes: 18 additions & 0 deletions src/components/header/Sort.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
function Sort({ setSortedItems }) {
function sortProducts(e) {
setSortedItems(e.target.value)
}

return (
<div>
<label htmlFor="sort">Sort </label>
<select name="sort" id="sort" onChange={sortProducts}>
<option value="default">Select sorting</option>
<option value="alphabetically">Alphabetically</option>
<option value="price">Price</option>
</select>
</div>
)
}

export default Sort
44 changes: 44 additions & 0 deletions src/components/header/StoreItemLi.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useState } from "react"

function StoreItemLi({ setCartItem, cartItem, filteredItems}) {
const [details, setDetails] = useState('')

function handleClick(item) {
const foundItem = cartItem.find(product => product.id === item.id)

if (foundItem) {
foundItem.quantity++
setCartItem([
...cartItem
])

} else {
const productToAdd = { ...item }
productToAdd.quantity = 1
setCartItem([
...cartItem,
productToAdd
])
}

}

function handleDetails(item) {
setDetails(item)
}

return filteredItems.map((item, index) => {
return (
<li key={index}>
<div className="store--item-icon">
<img src={`/assets/icons/${item.id}.svg`} alt={item.name} />
</div>
{details === item && <p className="details">{item.description}</p>}
<button onClick={() => handleClick(item)}>Add to cart</button>
<button onClick={() => handleDetails(item)}>Details</button>
</li>
)
})
}

export default StoreItemLi
11 changes: 11 additions & 0 deletions src/components/header/StoreItemUl.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import StoreItemLi from './StoreItemLi'

function StoreItemUl({ setCartItem, cartItem, filteredItems}) {
return (
<ul className="item-list store--item-list">
<StoreItemLi setCartItem={setCartItem} cartItem={cartItem} filteredItems={filteredItems} />
</ul>
)
}

export default StoreItemUl
40 changes: 40 additions & 0 deletions src/components/main/CartItemLi.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
function CartItemLi({ item, cartItem, setCartItem }) {
function handleMinusClick() {
if (item.quantity === 1) {
const index = cartItem.findIndex(product => product.id === item.id)
cartItem.splice(index, 1)
setCartItem([
...cartItem
])
return;
}

item.quantity--
setCartItem([
...cartItem
])
}

function handlePlusClick() {
item.quantity++
setCartItem([
...cartItem
])
}

return (
<li>
<img
className="cart--item-icon"
src={`assets/icons/${item.id}.svg`}
alt={item.name}
/>
<p>{item.name}</p>
<button className="quantity-btn remove-btn center" onClick={handleMinusClick}>-</button>
<span className="quantity-text center">{item.quantity}</span>
<button className="quantity-btn add-btn center" onClick={handlePlusClick}>+</button>
</li>
)
}

export default CartItemLi
13 changes: 13 additions & 0 deletions src/components/main/CartItemUl.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import CartItemLi from "./CartItemLi"

function CartItemUl({ cartItem, setCartItem }) {
return (
<ul className="item-list cart--item-list">
{cartItem.map((item, index) => {
return <CartItemLi key={index} item={item} cartItem={cartItem} setCartItem={setCartItem}/>
})}
</ul>
)
}

export default CartItemUl
24 changes: 24 additions & 0 deletions src/components/main/MainComponent.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import CartItemUl from "./CartItemUl"

function MainComponent({ cartItem, setCartItem}) {
const total = (cartItem.reduce((total, item) => total += item.price * item.quantity, 0)).toFixed(2)

return (
<main id="cart">
<h2>Your Cart</h2>
<div className="cart--item-list-container">
<CartItemUl cartItem={cartItem} setCartItem={setCartItem}/>
</div>
<div className="total-section">
<div>
<h3>Total</h3>
</div>
<div>
<span className="total-number">£{total}</span>
</div>
</div>
</main>
)
}

export default MainComponent
4 changes: 2 additions & 2 deletions src/store-items.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const storeItems = [
{
id: "005-avocado",
name: "avocado",
price: 0.35,
price: 0.37,
description: "The avocado, alligator pear or avocado pear (Persea americana) is a medium-sized, evergreen tree in the laurel family (Lauraceae).",
type: "fruit"
},
Expand All @@ -45,7 +45,7 @@ const storeItems = [
{
id: "007-bell-pepper",
name: "bell pepper",
price: 0.35,
price: 0.36,
description: "The bell pepper (also known as sweet pepper, pepper, capsicum /ˈkæpsɪkəm/ or in some places, mangoes) is the fruit of plants in the Grossum Group of the species Capsicum annuum.",
type: "fruit"
},
Expand Down
4 changes: 4 additions & 0 deletions src/styles/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ button {
height: 125px;
}

.details {
font-size: 0.8rem;
}

@media only screen and (max-width: 600px) {
.store--item-list {
grid-template-columns: repeat(3, 125px);
Expand Down