|
| 1 | +const MEALS = [ |
| 2 | + { description: 'Breakfast', calories: 460 }, |
| 3 | + { description: 'Snack', calories: 180 }, |
| 4 | + { description: 'Lunch', calories: 600 }, |
| 5 | +]; |
| 6 | + |
| 7 | +const { td, th, tr, tbody, thead, table } = tags; |
| 8 | + |
| 9 | +function cell(tag, className, value) { |
| 10 | + return tag({className}, value); |
| 11 | +} |
| 12 | + |
| 13 | +function mealRow(className, meal) { |
| 14 | + return tr({ className }, [ |
| 15 | + cell(td, 'pa2', meal.description), |
| 16 | + cell(td, 'pa2 tr', meal.calories), |
| 17 | + ]); |
| 18 | +} |
| 19 | + |
| 20 | +function mealsBody(className, meals) { |
| 21 | + const rows = R.map(R.partial(mealRow, ['stripe-dark']), meals) |
| 22 | + const rowsWithTotal = R.append(totalRow(meals), rows) |
| 23 | + |
| 24 | + return tbody({ className }, rowsWithTotal); |
| 25 | +} |
| 26 | + |
| 27 | +const headerRow= tr([ |
| 28 | + cell(th, 'pa2 tl', 'Meal'), |
| 29 | + cell(th, 'pa2 tr', 'Calories') |
| 30 | +]) |
| 31 | + |
| 32 | +const mealHeader = thead(headerRow) |
| 33 | + |
| 34 | +function totalRow(meals) { |
| 35 | + const total = R.pipe( |
| 36 | + R.map(meal => meal.calories), |
| 37 | + R.reduce((acc, calories) => acc + calories, 0) |
| 38 | + )(meals) |
| 39 | + |
| 40 | + return tr({ className: 'bt b'}, [ |
| 41 | + cell(td, 'pa2 tr', 'Total:'), |
| 42 | + cell(td, 'pa2 tr', total), |
| 43 | + ]) |
| 44 | +} |
| 45 | + |
| 46 | +function mealsTable(meals) { |
| 47 | + return table( { className: 'mw5 center w-100 collapse' }, [ |
| 48 | + mealHeader, |
| 49 | + mealsBody('', meals) |
| 50 | + ]) |
| 51 | +} |
| 52 | + |
| 53 | +const node = document.getElementById('app'); |
| 54 | + |
| 55 | +const view = mealsTable(MEALS); |
| 56 | + |
| 57 | +node.appendChild(view); |
0 commit comments