feat: orchestrator usage across MFs (#1)
This commit is contained in:
parent
fbcaac6ec1
commit
df661089e5
5 changed files with 112 additions and 57 deletions
|
|
@ -1,71 +1,102 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
// import { broadcast } from 'utils/orchestrator'
|
import { broadcast, listen } from "utils";
|
||||||
import React, { useState } from "react";
|
import React, { Component } 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,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// listen to add-to-cart messages
|
class Cart extends Component {
|
||||||
// if item is already in cart, increment count
|
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 products.reduce((acc, product) => {
|
||||||
return acc + product.price * product.count;
|
return acc + product.price * product.count;
|
||||||
}, 0);
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
const decreaseCount = (index) => {
|
addProduct = (product) => {
|
||||||
// if in cart, decrease count
|
const { products } = this.state;
|
||||||
const updatedProducts = [...products];
|
const index = products.findIndex((p) => p.name === product.name);
|
||||||
if (updatedProducts[index].count > 1) {
|
if (index > -1) {
|
||||||
updatedProducts[index].count--;
|
const updatedProducts = [...products];
|
||||||
|
updatedProducts[index].count++;
|
||||||
|
this.setState({ products: updatedProducts });
|
||||||
} else {
|
} else {
|
||||||
updatedProducts.splice(index, 1);
|
this.setState({ products: [...products, { ...product, count: 1 }] });
|
||||||
}
|
}
|
||||||
setProducts(updatedProducts);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const increaseCount = (index) => {
|
removeProduct = (product) => {
|
||||||
// if in cart, increase count
|
const { products } = this.state;
|
||||||
const updatedProducts = [...products];
|
const index = products.findIndex((p) => p.name === product.name);
|
||||||
updatedProducts[index].count++;
|
if (index > -1) {
|
||||||
setProducts(updatedProducts);
|
const updatedProducts = [...products];
|
||||||
|
updatedProducts[index].count--;
|
||||||
|
this.setState({ products: updatedProducts });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
componentDidMount() {
|
||||||
<div>
|
broadcast("update-count", this.getTotalItems());
|
||||||
<h2>🛒 Cart</h2>
|
listen("add-product", this.addProduct);
|
||||||
<ul>
|
}
|
||||||
{products.map((product, index) => (
|
|
||||||
<li key={index}>
|
|
||||||
<span>({product.count}x) </span>
|
|
||||||
<span>{product.name}</span>
|
|
||||||
<span> - </span>
|
|
||||||
<strong>${product.price * product.count}</strong>
|
|
||||||
<span>
|
|
||||||
<button onClick={() => decreaseCount(index)}> - </button>
|
|
||||||
<button onClick={() => increaseCount(index)}> + </button>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<span>Total: </span>
|
componentDidUpdate(prevProps, prevState) {
|
||||||
<strong>${getTotal()}</strong>
|
const { products } = this.state;
|
||||||
</div>
|
if (prevState.products !== products) {
|
||||||
);
|
broadcast("update-count", this.getTotalItems());
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { products } = this.state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>🛒 Cart</h2>
|
||||||
|
<ul>
|
||||||
|
{products.map((product, index) => (
|
||||||
|
<li key={index}>
|
||||||
|
<span>({product.count}x) </span>
|
||||||
|
<span>{product.name}</span>
|
||||||
|
<span> - </span>
|
||||||
|
<strong>${product.price * product.count}</strong>
|
||||||
|
<span>
|
||||||
|
<button onClick={() => this.removeProduct(product)}> - </button>
|
||||||
|
<button onClick={() => this.addProduct(product)}> + </button>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<span>Total: </span>
|
||||||
|
<strong>${this.getTotalPrice()}</strong>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default Cart;
|
export default Cart;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import React from "react";
|
import { listen } from "utils";
|
||||||
|
import React, { useEffect } from "react";
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
|
|
||||||
const App = (props) => {
|
const App = (props) => {
|
||||||
|
|
@ -6,6 +7,11 @@ const App = (props) => {
|
||||||
const [count, setCount] = React.useState(0);
|
const [count, setCount] = React.useState(0);
|
||||||
|
|
||||||
// listen to add-to-cart messages
|
// listen to add-to-cart messages
|
||||||
|
useEffect(() =>
|
||||||
|
listen("update-count", (count) => {
|
||||||
|
setCount(count);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="app-b">
|
<section className="app-b">
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { broadcast } from "utils";
|
||||||
import styles from "./App.module.css";
|
import styles from "./App.module.css";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
|
@ -25,8 +26,8 @@ function App() {
|
||||||
];
|
];
|
||||||
|
|
||||||
const addToCart = (product) => {
|
const addToCart = (product) => {
|
||||||
console.log(">>> add to cart", product);
|
|
||||||
// broadcast add product to cart
|
// broadcast add product to cart
|
||||||
|
broadcast("add-product", product);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export { broadcast, listen } from "./orchestrator.mjs";
|
||||||
|
|
@ -1,3 +1,19 @@
|
||||||
// implement messaging system between MF's
|
// implement messaging system between MF's
|
||||||
|
const listeners = {};
|
||||||
|
|
||||||
// - broadcast message
|
// - broadcast message
|
||||||
// - listen to message & attach callback
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue