cc733b08 |
import React from "react";
import * as gf from "../src/genfuns";
import * as m from "./Model";
|
a00b5a50 |
class Summary {
|
cc733b08 |
constructor(wrapper = "span") {
|
a00b5a50 |
this.wrapper = wrapper;
}
}
|
cc733b08 |
class Detail {}
|
a00b5a50 |
|
cc733b08 |
const total_receipt = items =>
items.reduce((acc, item) => acc + item.subtotal, 0);
|
a00b5a50 |
const subtotal = items => items.reduce((acc, item) => acc + item.price, 0);
const total_tax = items => items.reduce((acc, item) => acc + item.tax, 0);
const display_money = amount => amount.toFixed(2);
const ItemLabel = ({ desc, amount, wrapper, ...restProps }) =>
|
cc733b08 |
React.createElement(wrapper, restProps, [
<span className="desc" key="0">
{" "}
{desc}:{" "}
</span>,
<span className="price" key="1">
{display_money(amount)}
</span>,
]);
|
a00b5a50 |
|
cc733b08 |
export const Items = gf
.defgeneric("Items", "animaltorender")
|
a00b5a50 |
.primary([gf.Shape("items", "view")], ({ items, view }) => Items(items, view))
.primary([Array, Summary], (items, view) => (
<>
|
cc733b08 |
<ItemLabel
desc="Subtotal"
amount={subtotal(items)}
wrapper={view.wrapper}
/>
|
a00b5a50 |
<ItemLabel desc="Tax" amount={total_tax(items)} wrapper={view.wrapper} />
|
cc733b08 |
<ItemLabel
desc="Total"
amount={total_receipt(items)}
wrapper={view.wrapper}
/>
|
a00b5a50 |
</>
))
.primary([Array, Detail], items => (
<ul>
|
cc733b08 |
{items.map(
(a, idx) => (
<Item item={a} key={idx} />
),
items
)}
<Items items={items} view={new Summary("li")} />
|
a00b5a50 |
</ul>
|
cc733b08 |
)).fn;
|
a00b5a50 |
|
cc733b08 |
export const Item = gf
.defgeneric("Item", "itemtorender")
|
a00b5a50 |
.primary([gf.Shape("item")], ({ item }) => Item(item))
.around([m.Item], function (_) {
const [desc, price] = this.call_next_method();
|
cc733b08 |
return <ItemLabel desc={desc} amount={price} wrapper="li" />;
|
a00b5a50 |
})
.primary([m.NonFood], item => ["Non-food Item", item.price])
.primary([m.NormalFood], item => ["Food", item.price])
|
cc733b08 |
.primary([m.AlcoholicBeverage], item => ["Alcohol", item.price]).fn;
|
a00b5a50 |
|
cc733b08 |
export const Receipt = ({ items }) => (
|
a00b5a50 |
<div>
|
cc733b08 |
<h1>
<Items {...{ items }} view={new Summary()} />
</h1>
|
a00b5a50 |
<Items {...{ items }} view={new Detail()} />
</div>
);
|