From 6babd2bee09eaf88ff8ffc38033c479eca988c9a Mon Sep 17 00:00:00 2001
From: Mike Smith <89040888+smiggiddy@users.noreply.github.com>
Date: Thu, 17 Oct 2024 12:34:45 -0400
Subject: [PATCH] basic features
---
shopping-cart/src/Cart.jsx | 103 ++++++++++++++----
shopping-cart/src/Store.jsx | 8 +-
.../components/productCollection.module.css | 2 +-
.../src/components/productDetails.jsx | 55 ++++++----
.../src/components/productDetails.module.css | 16 +++
shopping-cart/src/components/products.jsx | 8 +-
.../src/components/products.module.css | 2 +
shopping-cart/src/utils/currency.js | 3 +
8 files changed, 146 insertions(+), 51 deletions(-)
create mode 100644 shopping-cart/src/components/productDetails.module.css
create mode 100644 shopping-cart/src/utils/currency.js
diff --git a/shopping-cart/src/Cart.jsx b/shopping-cart/src/Cart.jsx
index 06e918c..e1ba498 100644
--- a/shopping-cart/src/Cart.jsx
+++ b/shopping-cart/src/Cart.jsx
@@ -1,51 +1,106 @@
import PropTypes from "prop-types";
import styles from "./css/cart.module.css";
import { useOutletContext } from "react-router-dom";
+import { currencyFormat } from "./utils/currency";
const Cart = () => {
- const [cart, setCart, items, SetItems] = useOutletContext();
+ const [cart, setCart] = useOutletContext();
- const cartItems = Object.keys(cart);
+ const cartKeys = Object.keys(cart);
return (
- <>
-
- {cart ? (
-
-
Cart
- {cartItems.map((item, index) => (
-
- ))}
-
- ) : (
-
Your cart is empty
- )}
-
- >
+
+
Cart
+
+
);
};
-function CartItem({ item }) {
+function Bag({ cartKeys, cart, setCart }) {
+ return (
+ <>
+ {cartKeys.length > 0 ? (
+
+ {cartKeys.map((key, index) => (
+
+ ))}
+
+ ) : (
+ Your cart is empty
+ )}
+ >
+ );
+}
+
+function CartItem({ item, cart, setCart }) {
const { title, price, image, qty } = item;
return (
-
{title}
-
Qty: {qty}
-
Price: {price}
-
Total: {price * qty}
-
{item.id}
+
+
{title}
+
Price: ${currencyFormat(price)}
+
Qty: {qty}
+
+
+
+
{qty}
+
+
+
+
Total: {currencyFormat(qty * price)}
+
+
);
}
+function increaseQty(item, cart, setCart) {
+ if (cart[item.id]) {
+ let obj = { ...cart };
+ obj[item.id].qty += 1;
+ setCart(obj);
+ }
+}
+
+function decreaseQty(item, cart, setCart) {
+ if (cart[item.id]) {
+ let obj = { ...cart };
+ if (obj[item.id].qty > 1) obj[item.id].qty -= 1;
+ setCart(obj);
+ }
+}
+
+function removeFromCart(item, cart, setCart) {
+ if (cart[item.id]) {
+ let obj = { ...cart };
+ delete obj[item.id];
+ setCart(obj);
+ }
+}
+
CartItem.propTypes = {
item: PropTypes.object,
+ cart: PropTypes.object,
+ setCart: PropTypes.func,
};
-Cart.propTypes = {
- cart: PropTypes.array,
+Bag.propTypes = {
+ cartKeys: PropTypes.array,
+ cart: PropTypes.object,
+ setCart: PropTypes.func,
};
export default Cart;
diff --git a/shopping-cart/src/Store.jsx b/shopping-cart/src/Store.jsx
index c0dc81e..017663c 100644
--- a/shopping-cart/src/Store.jsx
+++ b/shopping-cart/src/Store.jsx
@@ -10,7 +10,7 @@ export default function Store() {
return (
-
Smig.Tech Coaching Store
+
Smig.Tech Store
{
if (response.status >= 400) {
throw new Error("unable to fetch items");
@@ -40,7 +42,7 @@ function useFakeStoreAPIData(items, setItems, loading, setLoading) {
response.forEach((item) => {
arr.push({
title: item.title,
- price: item.price,
+ price: item.price * 100,
image: item.image,
id: crypto.randomUUID(),
});
diff --git a/shopping-cart/src/components/productCollection.module.css b/shopping-cart/src/components/productCollection.module.css
index dbbfe00..0d26554 100644
--- a/shopping-cart/src/components/productCollection.module.css
+++ b/shopping-cart/src/components/productCollection.module.css
@@ -8,7 +8,7 @@
.card {
display: flex;
flex-direction: column;
- max-width: calc(100% / 4);
+ max-width: calc(100% / 5);
justify-content: end;
/*flex: 1;*/
padding: 1.5rem;
diff --git a/shopping-cart/src/components/productDetails.jsx b/shopping-cart/src/components/productDetails.jsx
index 3b02bd1..13f85c7 100644
--- a/shopping-cart/src/components/productDetails.jsx
+++ b/shopping-cart/src/components/productDetails.jsx
@@ -1,47 +1,62 @@
-import { useParams, useOutletContext } from "react-router-dom";
+import { useParams, useOutletContext, Link } from "react-router-dom";
import Products from "./products";
-import PropTypes from "prop-types";
-import styles from "./productCollection.module.css";
+import styles from "./productDetails.module.css";
export default function ProductDetails() {
- const [cart, setCart, items, setItems] = useOutletContext();
+ const [cart, setCart, items] = useOutletContext();
const { id } = useParams();
- const item = items.filter((item) => item.id === id)[0];
+
+ if (!items) return ;
+ const item = items.find((item) => item.id === id);
return (
{item ? (
+
Back
+
View Cart
- ) : null}
+ ) : (
+
+ )}
+
+ );
+}
+
+function HandleInvalidItem() {
+ return (
+
+
+
Product Does Not Exist!
+ Return to Store
+
);
}
function addToCart(item, cart, setCart) {
let obj = { ...cart };
- if (obj[item.id]) {
- obj[item.id].qty += 1;
- } else {
- obj[item.id] = item;
- obj[item.id].qty = 1;
- }
-
+ obj[item.id] = item;
+ obj[item.id].qty = 1;
setCart(obj);
}
-ProductDetails.propTypes = {
- item: PropTypes.object,
- cart: PropTypes.object,
- setCart: PropTypes.func,
-};
+function removeFromCart(item, cart, setCart) {
+ if (cart[item.id]) {
+ let obj = { ...cart };
+ delete obj[item.id];
+ setCart(obj);
+ }
+}
diff --git a/shopping-cart/src/components/productDetails.module.css b/shopping-cart/src/components/productDetails.module.css
new file mode 100644
index 0000000..0d26554
--- /dev/null
+++ b/shopping-cart/src/components/productDetails.module.css
@@ -0,0 +1,16 @@
+.container {
+ display: flex;
+ gap: 2rem;
+ justify-content: center;
+ flex-wrap: wrap;
+ align-items: stretch;
+}
+.card {
+ display: flex;
+ flex-direction: column;
+ max-width: calc(100% / 5);
+ justify-content: end;
+ /*flex: 1;*/
+ padding: 1.5rem;
+ margin: 1.5rem;
+}
diff --git a/shopping-cart/src/components/products.jsx b/shopping-cart/src/components/products.jsx
index 2adf8a2..6c58aa4 100644
--- a/shopping-cart/src/components/products.jsx
+++ b/shopping-cart/src/components/products.jsx
@@ -2,13 +2,15 @@ import PropTypes from "prop-types";
import styles from "./products.module.css";
+import { currencyFormat } from "../utils/currency";
+
export default function Products({ item, cart, setCart }) {
return (
-
+ <>
{item.title}
-
${item.price}
-
+ ${currencyFormat(item.price)}
+ >
);
}
diff --git a/shopping-cart/src/components/products.module.css b/shopping-cart/src/components/products.module.css
index fc99ff0..302ced5 100644
--- a/shopping-cart/src/components/products.module.css
+++ b/shopping-cart/src/components/products.module.css
@@ -2,4 +2,6 @@
width: 100%;
height: auto;
vertical-align: middle;
+ object-fit: cover;
+ float: left;
}
diff --git a/shopping-cart/src/utils/currency.js b/shopping-cart/src/utils/currency.js
new file mode 100644
index 0000000..03bd066
--- /dev/null
+++ b/shopping-cart/src/utils/currency.js
@@ -0,0 +1,3 @@
+export function currencyFormat(str) {
+ return (str / 100).toFixed(2);
+}