- render() bodies: one HTML line per 'h = h ..' statement, single-
quoted attributes, ${} holes, esc() on data — el() chains gone
- discovered + recorded gap #3: no multi-line expressions or literals
(leading/trailing .. and paren grouping all reject at NEWLINE) —
exactly the tax story 37's raw literal deletes
- 37-target comment blocks dropped (bodies now self-explanatory; the
README states the delta); rebuilt + full buy-flow re-smoked (178.0
total, stock 12->10, 409, traversal 404)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
53 lines
1.3 KiB
Text
53 lines
1.3 KiB
Text
-- orders/view.wo — the confirmation page and the orders table.
|
||
-- Markup-first, one HTML line per statement; see product_list/view.wo
|
||
-- for the convention and the story-37 endgame.
|
||
use html
|
||
|
||
pub class OrderOk {
|
||
name: Text
|
||
qty: Int
|
||
total: Float
|
||
|
||
fn render() -> Text {
|
||
let h = "<div class='card'>";
|
||
h = h .. "<h1>Order placed</h1>";
|
||
h = h .. "<p>${self.qty} × ${esc(self.name)} — total € ${self.total}</p>";
|
||
h = h .. "<p><a href='/orders'>See all orders</a> · <a href='/'>Keep shopping</a></p>";
|
||
h = h .. "</div>";
|
||
return h;
|
||
}
|
||
}
|
||
|
||
pub class OrderRow {
|
||
name: Text
|
||
qty: Int
|
||
total: Float
|
||
status: Text
|
||
|
||
fn render() -> Text {
|
||
let h = "<tr>";
|
||
h = h .. "<td>${esc(self.name)}</td>";
|
||
h = h .. "<td>${self.qty}</td>";
|
||
h = h .. "<td>€ ${self.total}</td>";
|
||
h = h .. "<td>${esc(self.status)}</td>";
|
||
h = h .. "</tr>";
|
||
return h;
|
||
}
|
||
}
|
||
|
||
pub class OrdersPage {
|
||
rows: Text
|
||
|
||
fn render() -> Text {
|
||
let h = "<h1>Orders</h1>";
|
||
if self.rows == "" {
|
||
h = h .. "<p>No orders yet — <a href='/'>go buy something</a>.</p>";
|
||
return h;
|
||
}
|
||
h = h .. "<table class='orders'>";
|
||
h = h .. "<tr><th>Product</th><th>Qty</th><th>Total</th><th>Status</th></tr>";
|
||
h = h .. "${self.rows}";
|
||
h = h .. "</table>";
|
||
return h;
|
||
}
|
||
}
|