Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add order confirmation chapter #9

Merged
merged 12 commits into from
Dec 8, 2023
1 change: 1 addition & 0 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export default defineConfig({
{ text: 'Celsius Converter', link: '/celsius-converter-exception/' },
{ text: 'Celsius Converter using Option', link: '/celsius-converter-option/' },
{ text: 'Introduction to Dune', link: '/intro-to-dune/' },
{ text: 'Order Confirmation', link: '/order-confirmation/' },
]
}
],
Expand Down
151 changes: 151 additions & 0 deletions docs/order-confirmation/Snippets.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
module ItemV1 = {
// #region type-t
type t =
| Sandwich
| Burger;
// #endregion type-t

// #region to-price
let toPrice = t =>
switch (t) {
| Sandwich => 10.
| Burger => 15.
};
// #endregion to-price
};

module Item = {
type t =
| Sandwich
| Burger;

// #region to-price-fun
let toPrice =
fun
| Sandwich => 10.
| Burger => 15.;
// #endregion to-price-fun

// #region to-emoji
let toEmoji =
fun
| Sandwich => {js|🥪|js}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized we could mention that {js||js} is Melange-specific, and it's not available in native OCaml.

Maybe we could come up with some kind of tips, I noticed vitepress supports them:

::: tip
This is a tip.
:::

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a tip in the chapter where we first covered {js||js} strings: d4aa3b7

| Burger => {js|🍔|js};
// #endregion to-emoji

// #region make
[@react.component]
let make = (~item: t) =>
<tr>
<td> {item |> toEmoji |> React.string} </td>
<td>
{item
|> toPrice
|> Js.Float.toFixedWithPrecision(~digits=2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heads up: these functions are being modified with Melange v3: melange-re/melange#673

No action needed, just once v3 is released we'll have to remember to update the book so that all snippets compile.

|> React.string}
</td>
</tr>;
// #endregion make
};

module Order = {
// #region order
type t = array(Item.t);

[@react.component]
let make = (~items: t) => {
let total =
items
|> Js.Array.reduce((acc, order) => acc +. Item.toPrice(order), 0.);

<table>
<tbody>
{items |> Js.Array.map(item => <Item item />) |> React.array}
<tr>
<td> {React.string("Total")} </td>
<td>
{total |> Js.Float.toFixedWithPrecision(~digits=2) |> React.string}
</td>
</tr>
Comment on lines +64 to +69
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is minor, but could be put into a Total component.

</tbody>
</table>;
};
// #endregion order

let makeWithItemRows = (~items: t) => {
// #region order-make-item-rows
let total =
items
|> Js.Array.reduce((acc, order) => acc +. Item.toPrice(order), 0.);

let itemRows = items |> Js.Array.map(item => <Item item />);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to add the explicit annotation here? As I read the text that uses this code, I noticed it's talking about the types themselves:

To better see what types are at play, it might make sense to refactor
`Order.make` like so:

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added type annotation in 6634e59 and also added an explanation that React.array doesn't change the underlying JS object.


<table>
<tbody>
{itemRows |> React.array}
<tr>
<td> {React.string("Total")} </td>
<td>
{total |> Js.Float.toFixedWithPrecision(~digits=2) |> React.string}
</td>
</tr>
</tbody>
</table>;
// #endregion order-make-item-rows
};
};

module Index = {
// #region index
module App = {
let items: Order.t = [|Sandwich, Burger, Sandwich|];

[@react.component]
let make = () =>
<div>
<h1> {React.string("Order confirmation")} </h1>
<Order items />
</div>;
};

let node = ReactDOM.querySelector("#root");
switch (node) {
| None =>
Js.Console.error("Failed to start React: couldn't find the #root element")
| Some(root) => ReactDOM.render(<App />, root)
};
// #endregion index
};

let _ = {
let items = [||];
// #region mapi
items
|> Js.Array.mapi((item, index) =>
<Item key={"item-" ++ string_of_int(index)} item />
)
|> React.array
// #endregion mapi
|> ignore;
};

module ItemV2 = {
// #region hotdog
type t =
| Sandwich
| Burger
| Hotdog;

let toPrice =
fun
| Sandwich => 10.
| Burger => 15.
| Hotdog => 5.;

let toEmoji =
fun
| Sandwich => {js|🥪|js}
| Burger => {js|🍔|js}
| Hotdog => {js|🌭|js};
// #endregion hotdog
};
6 changes: 6 additions & 0 deletions docs/order-confirmation/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(melange.emit
(target output)
(libraries reason-react)
(preprocess
(pps melange.ppx reason-react-ppx))
(module_systems es6))
Loading