millerm30 / chore-bucks

Chore Bucks. Kids complete chores for points.
4 stars 0 forks source link

June 29th session refactors #20

Closed jackharrhy closed 2 years ago

jackharrhy commented 2 years ago
diff --git a/src/App.js b/src/App.js
index 6cfde6f..04a653c 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,6 +1,13 @@
 import { ChoresProvider } from "./contexts/Chores";
 import { ShoppingProvider } from "./contexts/Shopping";
+import { WishlistProvider } from "./contexts/Wishlist";

-export default function App({ children, addPoints }) {
-    return <ShoppingProvider><ChoresProvider addPoints={addPoints}>{children}</ChoresProvider></ShoppingProvider>;
-}
\ No newline at end of file
+export default function App({ children, points, addPoints, removePoints }) {
+  return (
+    <ShoppingProvider points={points} removePoints={removePoints}>
+      <WishlistProvider>
+        <ChoresProvider addPoints={addPoints}>{children}</ChoresProvider>
+      </WishlistProvider>
+    </ShoppingProvider>
+  );
+}
diff --git a/src/components/Cart.js b/src/components/Cart.js
index 2d8d6c6..252eba0 100644
--- a/src/components/Cart.js
+++ b/src/components/Cart.js
@@ -1,12 +1,11 @@
 import React from "react";
 import { useShopping } from "../contexts/Shopping";
-import {v4 as uuid} from "uuid";
+import { v4 as uuid } from "uuid";
 import { GoTrashcan } from "react-icons/go";

 const Cart = ({ points }) => {
+  const { cart, removeFromCartHandler, purchaseCartHandler } = useShopping();

-  const { addToCart, removeFromCartHandler, purchaseCartHandler } = useShopping();
-   
   return (
     <main className="text-center">
       <section className="pt-10 mb-12">
@@ -17,12 +16,12 @@ const Cart = ({ points }) => {
         <h2 className="text-2xl font-semi-bold p-1">
           Available Chore Bucks ๐Ÿ’ฐ{points}
         </h2>
-        {addToCart.length === 0 && (
+        {cart.length === 0 && (
           <p className="italic pt-4">No items added to your cart!</p>
         )}
         {
           <div className="w-full mx-auto mt-10">
-            {addToCart.map((wish) => (
+            {cart.map((wish) => (
               <div
                 key={uuid()}
                 className="container flex flex-row justify-center w-full items-center py-3 mx-auto"
@@ -45,24 +44,24 @@ const Cart = ({ points }) => {
             ))}
           </div>
         }
-          <div className="container flex flex-col justify-center w-full items-center py-3 mx-auto">
-            <span>
-              <h2 className="text-left text-md md:text-xl underline">
-                Cart Total: ๐Ÿ’ฐ
-                {addToCart.reduce((acc, curr) => acc + curr.points, 0)}
-              </h2>
-            </span>
-            <button
-              disabled={addToCart.length === 0}
-              onClick={purchaseCartHandler}
-              className="bg-blue-400 my-4 self-center px-4 py-2 border-2 border-blue-600 rounded-lg hover:bg-blue-500">
-              Purchase
-            </button>
-          </div>
-      
+        <div className="container flex flex-col justify-center w-full items-center py-3 mx-auto">
+          <span>
+            <h2 className="text-left text-md md:text-xl underline">
+              Cart Total: ๐Ÿ’ฐ
+              {cart.reduce((acc, curr) => acc + curr.points, 0)}
+            </h2>
+          </span>
+          <button
+            disabled={cart.length === 0}
+            onClick={purchaseCartHandler}
+            className="bg-blue-400 my-4 self-center px-4 py-2 border-2 border-blue-600 rounded-lg hover:bg-blue-500"
+          >
+            Purchase
+          </button>
+        </div>
       </section>
     </main>
   );
-}
+};

-export default Cart
\ No newline at end of file
+export default Cart;
diff --git a/src/components/Wishlist.js b/src/components/Wishlist.js
index 4cb8e7b..d9657e3 100644
--- a/src/components/Wishlist.js
+++ b/src/components/Wishlist.js
@@ -1,74 +1,48 @@
-import React, {useState, useEffect} from "react";
-import {v4 as uuid} from "uuid";
+import { v4 as uuid } from "uuid";
 import Wishadd from "./Wishadd";
 import { GoTrashcan } from "react-icons/go";
-import toast from "react-hot-toast";
-import { useShopping } from "../contexts/Shopping";
+import { useWishlist } from "../contexts/Wishlist";

-function getInitialWishes() {
-  const store = localStorage.getItem("wishList");
-  const savedWishes = JSON.parse(store);
-  return savedWishes || [];
-};
-
-const WishList = ({ points }) => {
-  const [wishes, setWishes] = useState(getInitialWishes);
-  const { addToCart, addToCartHandler } = useShopping();
-
-  const addWish = (title, points) => {
-    toast.success(`${title} added to wish list!`);
-    setWishes([...wishes, {title, points, id: uuid()}])
-  };
-
-  const completeWish = (wish) => {
-    if (points >= wish.points) {
-      setWishes(wishes.filter((i) => i.id !== wish.id));
-      addToCartHandler(addToCart, wish.title, wish.points);
-      toast.success(`${wish.title} added to shopping cart! ๐Ÿš€`);
-    }
-    else {
-      toast.error(`You don't have enough points to buy ${wish.title}! Complete more chores! ๐Ÿงน`); 
-    }
-  };
-
-   const removeWish = (wish) => {
-     toast.error(`${wish.title} removed from wish list!`);
-     setWishes(wishes.filter((i) => i !== wish));
-   };
-
-  useEffect(() => {
-    const store = JSON.stringify(wishes)
-    localStorage.setItem("wishList", store)
-  }, [wishes]);
+const WishList = () => {
+  const { wishes, addWish, completeWish, removeWish } = useWishlist();

   return (
     <main>
       <Wishadd addWish={addWish} />
       {wishes.length === 0 && (
         <p className="text-center italic pt-4">No Wish List Items!</p>
-         )}
+      )}
       {
-      <section className="grid grid-cols-2 gap-5 py-5 mx-5 md:grid-cols-3 lg:grid-cols-4">
-        {wishes.map((wish) => (
-          <div key={uuid()} className="bg-[#f8f8f8] w-full px-2 py-1 mt-5 flex flex-col justify-start items-center border-2 border-blue-400 rounded-lg">
-            <button
-              onClick={() => removeWish(wish)}
-              className="text-2xl text-red-600 self-end">
-              <GoTrashcan />
-            </button>
-            <h2 className="text-xl font-semibold p-1 text-center">{wish.title}</h2>
-            <h3 className="text-lg font-semibold p-1 text-center">๐Ÿ’ฐ{wish.points} Points</h3>
-            <button
-                 onClick={() => completeWish(wish)}
-                 className="bg-blue-400 mb-4 self-center px-4 py-2 border-2 border-blue-600 rounded-lg hover:bg-blue-500">
-                   Add To Cart
-                 </button>
-          </div>
-        ))}
-      </section>
+        <section className="grid grid-cols-2 gap-5 py-5 mx-5 md:grid-cols-3 lg:grid-cols-4">
+          {wishes.map((wish) => (
+            <div
+              key={uuid()}
+              className="bg-[#f8f8f8] w-full px-2 py-1 mt-5 flex flex-col justify-start items-center border-2 border-blue-400 rounded-lg"
+            >
+              <button
+                onClick={() => removeWish(wish)}
+                className="text-2xl text-red-600 self-end"
+              >
+                <GoTrashcan />
+              </button>
+              <h2 className="text-xl font-semibold p-1 text-center">
+                {wish.title}
+              </h2>
+              <h3 className="text-lg font-semibold p-1 text-center">
+                ๐Ÿ’ฐ{wish.points} Points
+              </h3>
+              <button
+                onClick={() => completeWish(wish)}
+                className="bg-blue-400 mb-4 self-center px-4 py-2 border-2 border-blue-600 rounded-lg hover:bg-blue-500"
+              >
+                Add To Cart
+              </button>
+            </div>
+          ))}
+        </section>
       }
     </main>
   );
-}
+};

-export default WishList
\ No newline at end of file
+export default WishList;
diff --git a/src/contexts/Shopping.js b/src/contexts/Shopping.js
index 1d70f77..fa584e4 100644
--- a/src/contexts/Shopping.js
+++ b/src/contexts/Shopping.js
@@ -1,6 +1,6 @@
-import React, {useContext, useState, useEffect} from "react";
+import React, { useContext, useState, useEffect } from "react";
 import toast from "react-hot-toast";
-import {v4 as uuid} from "uuid";
+import { v4 as uuid } from "uuid";

 const ShoppingContext = React.createContext();

@@ -10,32 +10,44 @@ function getInitalCart() {
     : [];
 }

-export function ShoppingProvider({ children }) {
-    const [addToCart , setAddToCart] = useState(getInitalCart);
-
-    const addToCartHandler = (addToCart, title, points) => {
-        setAddToCart([...addToCart, {title: title, points: points, id: uuid()}]);
-    };
-
-    const removeFromCartHandler = (wish) => {
-        toast.error(`${wish.title} removed from shopping cart!`);
-        setAddToCart(addToCart.filter((i) => i !== wish));
-    };
-
-    const purchaseCartHandler = () => {
-        alert("Stay Tuned! This feature is coming soon!");
-    };
-
-    useEffect(() => {
-        localStorage.setItem("cartList", JSON.stringify(addToCart));
-    }
-    , [addToCart]);
-
-    return (
-        <ShoppingContext.Provider value={{ addToCart, addToCartHandler, removeFromCartHandler, purchaseCartHandler }}>
-        {children}
-        </ShoppingContext.Provider>
-    );
+export function ShoppingProvider({ points, removePoints, children }) {
+  const [cart, setCart] = useState(getInitalCart);
+
+  const addToCart = (itemTitle, itemPoints) => {
+    toast.success(`${itemTitle} added to shopping cart! ๐Ÿš€`);
+    setCart([...cart, { title: itemTitle, points: itemPoints, id: uuid() }]);
+  };
+
+  const removeFromCartHandler = (wish) => {
+    toast.error(`${wish.title} removed from shopping cart!`);
+    setCart(addToCart.filter((i) => i !== wish));
+  };
+
+  const purchaseCartHandler = () => {
+    alert("todo");
+    console.log({ points, removePoints });
+    // sum up the points in the cart into one value
+    // check if the current points are enough to cover the cost
+    // if so, 'purchase' the items (set cart to nothing), and remove points
+    // if not, error
+  };
+
+  useEffect(() => {
+    localStorage.setItem("cartList", JSON.stringify(cart));
+  }, [cart]);
+
+  return (
+    <ShoppingContext.Provider
+      value={{
+        cart,
+        addToCart,
+        removeFromCartHandler,
+        purchaseCartHandler,
+      }}
+    >
+      {children}
+    </ShoppingContext.Provider>
+  );
 }

-export const useShopping = () => useContext(ShoppingContext);
\ No newline at end of file
+export const useShopping = () => useContext(ShoppingContext);
diff --git a/src/contexts/Wishlist.js b/src/contexts/Wishlist.js
new file mode 100644
index 0000000..b813a7d
--- /dev/null
+++ b/src/contexts/Wishlist.js
@@ -0,0 +1,55 @@
+import React, { useContext, useState, useEffect } from "react";
+import toast from "react-hot-toast";
+import { v4 as uuid } from "uuid";
+import { useShopping } from "./Shopping";
+
+const WishlistContext = React.createContext();
+
+const localStorageKey = "wishList";
+
+function getInitialWishes() {
+  return localStorage.getItem(localStorageKey)
+    ? JSON.parse(localStorage.getItem(localStorageKey))
+    : [];
+}
+
+export function WishlistProvider({ children }) {
+  const { addToCart } = useShopping();
+
+  const [wishes, setWishes] = useState(getInitialWishes);
+
+  const addWish = (title, points) => {
+    toast.success(`${title} added to wish list!`);
+    setWishes([...wishes, { title, points, id: uuid() }]);
+  };
+
+  const completeWish = (wish) => {
+    addToCart(wish.title, wish.points);
+    setWishes(wishes.filter((i) => i.id !== wish.id));
+  };
+
+  const removeWish = (wish) => {
+    toast.error(`${wish.title} removed from wish list!`);
+    setWishes(wishes.filter((i) => i !== wish));
+  };
+
+  useEffect(() => {
+    const store = JSON.stringify(wishes);
+    localStorage.setItem(localStorageKey, store);
+  }, [wishes]);
+
+  return (
+    <WishlistContext.Provider
+      value={{
+        wishes,
+        addWish,
+        completeWish,
+        removeWish,
+      }}
+    >
+      {children}
+    </WishlistContext.Provider>
+  );
+}
+
+export const useWishlist = () => useContext(WishlistContext);
diff --git a/src/index.js b/src/index.js
index 614a6e5..60d9016 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,6 +1,6 @@
-import React, {useState} from "react";
+import React, { useEffect, useState } from "react";
 import ReactDOM from "react-dom/client";
-import {BrowserRouter, Routes, Route} from "react-router-dom";
+import { BrowserRouter, Routes, Route } from "react-router-dom";
 import "./index.css";
 import "tw-elements";
 import Layout from "./components/Layout";
@@ -19,32 +19,33 @@ function getBucksFromLocalStorage() {
     return Number(points);
   }
   return 0;
-};
+}

 const Main = () => {
   const [points, setPoints] = useState(() => getBucksFromLocalStorage());

-  const addPoints = (amount) => {
-    const newPoints = points + amount;
-    setPoints(newPoints);
-    localStorage.setItem("points", newPoints);
-};
+  const addPoints = (amount) => setPoints(points + amount);
+  const removePoints = (amount) => setPoints(points - amount);
+
+  useEffect(() => {
+    localStorage.setItem("points", points);
+  }, [points]);

-return(
-  <App addPoints={addPoints}>
-    <BrowserRouter basename="/chore-bucks">
-      <Routes>
-        <Route path="/" element={<Layout points={points}/>}>
-          <Route path="" element={<HeroPage />} />
-          <Route path="/chores" element={<ChoresPage />} />
-          <Route path="/choresadd" element={<ChoresaddPage />} />
-          <Route path="/wishlist" element={<WishlistPage points={points}/>} />
-          <Route path="/cart" element={<Cart points={points}/>} />
-        </Route>
-      </Routes>
-    </BrowserRouter>
-  </App>
-);
+  return (
+    <App points={points} addPoints={addPoints} removePoints={removePoints}>
+      <BrowserRouter basename="/chore-bucks">
+        <Routes>
+          <Route path="/" element={<Layout points={points} />}>
+            <Route path="" element={<HeroPage />} />
+            <Route path="/chores" element={<ChoresPage />} />
+            <Route path="/choresadd" element={<ChoresaddPage />} />
+            <Route path="/wishlist" element={<WishlistPage />} />
+            <Route path="/cart" element={<Cart points={points} />} />
+          </Route>
+        </Routes>
+      </BrowserRouter>
+    </App>
+  );
 };

 root.render(<Main />);
millerm30 commented 2 years ago

Shopping cart completed. Ready to smash those chores and make some chore bucks! Cart purchase will calculate points and remove from total available points if enough available and clear cart or will show an error if not enough points available for purchase.