diff --git a/src/App.jsx b/src/App.jsx index d28c0b3..8a511b9 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,6 +1,10 @@ import './styles/reset.css' import './styles/index.css' +import { useState } from 'react' +import StoreItem from './StoreItem' +import Cart from './Cart' + import initialStoreItems from './store-items' /* @@ -12,37 +16,81 @@ import initialStoreItems from './store-items' } What should a cart item look like? 🤔 - */ -console.log(initialStoreItems) + For reference for myself: + { + id: '001-beetroot', + name: 'beetroot', + price: 0.35, + amount: 5 + } + */ export default function App() { - // Setup state here... + const [cart, setCart] = useState([]) + const [storeItems, setStoreItems] = useState(initialStoreItems) + + // Check if item is already in cart + const countItemAppearences = (item) => { + const filteredList = cart.filter(((currentItem) => + currentItem.id === item.id + )) + return filteredList.length + } + + const addToCart = (item) => { + if(countItemAppearences(item) === 0) + setCart([...cart, { + id: item.id, + name: item.name, + price: item.price, + amount: 1 + }]) + + else { + const updatedCart = cart.map((currentItem) => + currentItem.id === item.id ? {...currentItem, amount:currentItem.amount + 1} : currentItem + ) + setCart(updatedCart) + } + } + + const removeFromCart = (item) => { + if(countItemAppearences(item) === 1 && item.amount <= 1) + { + const updatedCart = cart.filter((currentItem) => + currentItem.id !== item.id + ) + setCart(updatedCart) + } + else { + const updatedCart = cart.map((currentItem) => + currentItem.id === item.id ? {...currentItem, amount:currentItem.amount - 1} : currentItem + ) + setCart(updatedCart) + } + } return ( <>

Greengrocers

-
-

Your Cart

-
- -
-
-
-

Total

-
-
- £0.00 -
-
-
+
Icons made by + {props.cartItem.name} +

{props.cartItem.name}

+ + {props.cartItem.amount} + + + + ) +} + +export default CartItem \ No newline at end of file diff --git a/src/Cart/CartItem/style.css b/src/Cart/CartItem/style.css new file mode 100644 index 0000000..eafd9a8 --- /dev/null +++ b/src/Cart/CartItem/style.css @@ -0,0 +1,4 @@ +.cart--item-icon { + width: 24px; + } + \ No newline at end of file diff --git a/src/Cart/Filter/index.jsx b/src/Cart/Filter/index.jsx new file mode 100644 index 0000000..cb5acb4 --- /dev/null +++ b/src/Cart/Filter/index.jsx @@ -0,0 +1,28 @@ +import './style.css' + +function Filter(props) { + return ( + <> +
+
+ Filter by +
+ {props.storeItems.map((item, index) => + <> + props.handleSelect(item)} + > + + + + )} +
+ + ) +} + +export default Filter \ No newline at end of file diff --git a/src/Cart/Filter/style.css b/src/Cart/Filter/style.css new file mode 100644 index 0000000..416613a --- /dev/null +++ b/src/Cart/Filter/style.css @@ -0,0 +1,49 @@ +/* + Extension +*/ + +#filter-by--list { + background-color: #e7f4ea; + border-radius: 5px; + margin: 2px; + + display: grid; + + grid-template-rows: auto auto auto; + + grid-auto-flow: column; + align-items: center; + padding: 5px; + } + + #filter-by--title { + margin-bottom: -5px; + } + + .filter-by--items + label { + background-color:ghostwhite; + color: rgb(161, 161, 161); + + padding: 2%; + border-radius: 3px; + + transition: 100ms; + } + + .filter-by--items:hover + label { + background-color:rgb(251, 251, 255); + color: rgb(70, 70, 70); + + transition: 170ms; + } + + .filter-by--items:checked + label { + background-color: white; + color: black; + + transition: 100ms; + } + + input[type="checkbox"] { + display: none; + } \ No newline at end of file diff --git a/src/Cart/index.jsx b/src/Cart/index.jsx new file mode 100644 index 0000000..bd6bd19 --- /dev/null +++ b/src/Cart/index.jsx @@ -0,0 +1,63 @@ +import { useState } from 'react' + +import CartItem from "./CartItem" +import Filter from "./Filter" + +function Cart(props) { + const [filters, setFilters] = useState([]) + + let filteredCart = props.cart + if (filters.length !== 0) filteredCart = console.log("filters in place") + + const calculateTotal = () => { + let total = 0.0 + for(let item in props.cart) { + total += props.cart[item].price * props.cart[item].amount + } + return total + } + + const getTotal = () => { + const total = calculateTotal() + return `£${total.toFixed(2)}` + } + + const handleSelect = (item) => { + if(filters.filter((currentItem) => currentItem === item).length !== 0) + setFilters(filters.filter((currentItem) => currentItem !== item)) + else + setFilters([...filters, item]) + } + + return( +
+

Your Cart

+
+
    + {props.cart.map((cartItem, index) => + + )} +
+
+
+
+

Total

+
+
+ {getTotal()} +
+
+ +
+ ) +} + +export default Cart \ No newline at end of file diff --git a/src/StoreItem/index.jsx b/src/StoreItem/index.jsx new file mode 100644 index 0000000..bb96dfc --- /dev/null +++ b/src/StoreItem/index.jsx @@ -0,0 +1,16 @@ +import './style.css' + +function StoreItem(props) { + + return( +
  • +
    + {props.storeItem.name} +
    + +
  • + + ) +} + +export default StoreItem \ No newline at end of file diff --git a/src/StoreItem/style.css b/src/StoreItem/style.css new file mode 100644 index 0000000..9ad102b --- /dev/null +++ b/src/StoreItem/style.css @@ -0,0 +1,4 @@ +.store--item-icon { + width: 125px; + height: 125px; + } \ No newline at end of file diff --git a/src/styles/index.css b/src/styles/index.css index 0a04c2b..962354c 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -48,11 +48,6 @@ button { grid-row-gap: 0.5rem; } -.store--item-icon { - width: 125px; - height: 125px; -} - @media only screen and (max-width: 600px) { .store--item-list { grid-template-columns: repeat(3, 125px); @@ -118,9 +113,6 @@ button { border-bottom: none; } -.cart--item-icon { - width: 24px; -} .center { display: grid;