diff --git a/app-cart/src/Cart.jsx b/app-cart/src/Cart.jsx
index 3951afb..c1610ae 100644
--- a/app-cart/src/Cart.jsx
+++ b/app-cart/src/Cart.jsx
@@ -1,71 +1,102 @@
// @ts-check
-// import { broadcast } from 'utils/orchestrator'
-import React, { useState } from "react";
-const Cart = () => {
- const [products, setProducts] = useState([
- {
- name: "Shoe A",
- description: "It is a good shoe",
- price: 100,
- count: 2,
- },
- {
- name: "Shoe B",
- description: "It is a comfortable shoe",
- price: 120,
- count: 7,
- },
- ]);
+import { broadcast, listen } from "utils";
+import React, { Component } from "react";
- // listen to add-to-cart messages
- // if item is already in cart, increment count
+class Cart extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ products: [
+ {
+ name: "Shoe A",
+ description: "It is a good shoe",
+ price: 100,
+ count: 2,
+ },
+ {
+ name: "Shoe B",
+ description: "It is a comfortable shoe",
+ price: 120,
+ count: 7,
+ },
+ ],
+ };
+ }
- const getTotal = () => {
+ getTotalItems = () => {
+ const { products } = this.state;
+ return products.reduce((acc, product) => {
+ return acc + product.count;
+ }, 0);
+ };
+
+ getTotalPrice = () => {
+ const { products } = this.state;
return products.reduce((acc, product) => {
return acc + product.price * product.count;
}, 0);
};
- const decreaseCount = (index) => {
- // if in cart, decrease count
- const updatedProducts = [...products];
- if (updatedProducts[index].count > 1) {
- updatedProducts[index].count--;
+ addProduct = (product) => {
+ const { products } = this.state;
+ const index = products.findIndex((p) => p.name === product.name);
+ if (index > -1) {
+ const updatedProducts = [...products];
+ updatedProducts[index].count++;
+ this.setState({ products: updatedProducts });
} else {
- updatedProducts.splice(index, 1);
+ this.setState({ products: [...products, { ...product, count: 1 }] });
}
- setProducts(updatedProducts);
};
- const increaseCount = (index) => {
- // if in cart, increase count
- const updatedProducts = [...products];
- updatedProducts[index].count++;
- setProducts(updatedProducts);
+ removeProduct = (product) => {
+ const { products } = this.state;
+ const index = products.findIndex((p) => p.name === product.name);
+ if (index > -1) {
+ const updatedProducts = [...products];
+ updatedProducts[index].count--;
+ this.setState({ products: updatedProducts });
+ }
};
- return (
-
-
🛒 Cart
-
- {products.map((product, index) => (
- -
- ({product.count}x)
- {product.name}
- -
- ${product.price * product.count}
-
-
-
-
-
- ))}
-
+ componentDidMount() {
+ broadcast("update-count", this.getTotalItems());
+ listen("add-product", this.addProduct);
+ }
-
Total:
-
${getTotal()}
-
- );
-};
+ componentDidUpdate(prevProps, prevState) {
+ const { products } = this.state;
+ if (prevState.products !== products) {
+ broadcast("update-count", this.getTotalItems());
+ }
+ }
+
+ render() {
+ const { products } = this.state;
+
+ return (
+
+
🛒 Cart
+
+ {products.map((product, index) => (
+ -
+ ({product.count}x)
+ {product.name}
+ -
+ ${product.price * product.count}
+
+
+
+
+
+ ))}
+
+
+
Total:
+
${this.getTotalPrice()}
+
+ );
+ }
+}
export default Cart;
diff --git a/app-heading/src/App.jsx b/app-heading/src/App.jsx
index d5922d8..e0d34c3 100644
--- a/app-heading/src/App.jsx
+++ b/app-heading/src/App.jsx
@@ -1,4 +1,5 @@
-import React from "react";
+import { listen } from "utils";
+import React, { useEffect } from "react";
import "./App.css";
const App = (props) => {
@@ -6,6 +7,11 @@ const App = (props) => {
const [count, setCount] = React.useState(0);
// listen to add-to-cart messages
+ useEffect(() =>
+ listen("update-count", (count) => {
+ setCount(count);
+ })
+ );
return (
diff --git a/app-products/src/App.jsx b/app-products/src/App.jsx
index 6ae3222..7d4a067 100644
--- a/app-products/src/App.jsx
+++ b/app-products/src/App.jsx
@@ -1,3 +1,4 @@
+import { broadcast } from "utils";
import styles from "./App.module.css";
function App() {
@@ -25,8 +26,8 @@ function App() {
];
const addToCart = (product) => {
- console.log(">>> add to cart", product);
// broadcast add product to cart
+ broadcast("add-product", product);
};
return (
diff --git a/utils/index.js b/utils/index.js
index e69de29..f3fb4e4 100644
--- a/utils/index.js
+++ b/utils/index.js
@@ -0,0 +1 @@
+export { broadcast, listen } from "./orchestrator.mjs";
diff --git a/utils/orchestrator.mjs b/utils/orchestrator.mjs
index 2c27412..7856c19 100644
--- a/utils/orchestrator.mjs
+++ b/utils/orchestrator.mjs
@@ -1,3 +1,19 @@
// implement messaging system between MF's
+const listeners = {};
+
// - broadcast message
-// - listen to message & attach callback
\ No newline at end of file
+export function broadcast(action, data) {
+ window.parent.postMessage({ action, data });
+ console.log("broadcast", { action, data });
+}
+
+// - listen to message & attach callback
+export function listen(action, callback) {
+ window.parent.addEventListener("message", (event) => {
+ const { data } = event;
+
+ if (data.action === action) {
+ callback(data.data);
+ }
+ });
+}