1 import _ from "lodash";
2 import { CityWithLocation } from "../repository/city";
3 import { UnitTrainingQueueWithName } from "../repository/training-queue";
4 import { Unit } from "../repository/unit";
5 import { DateTime } from "luxon";
7 function progressBar(current: number, max: number): string {
8 const percent = Math.ceil((current/max) * 100);
10 <div class="progress-bar unit-training" style="background: background: var(--green-bg);
11 background: linear-gradient(90deg, var(--green-bg) 0%, var(--green-bg) ${percent}%, #000 ${percent}%); border-color: var(--green-border);">
17 export function renderUnitTraining(city: CityWithLocation, units: Unit[], trainingQueues: UnitTrainingQueueWithName[]): string {
18 const unit = _.keyBy(units, 'slug');
20 <div hx-trigger="reload-unit-training, every 600s" hx-get="/poll/unit-training">
21 <h2 data-augmented-ui="tl-clip bl-clip none">Unit Training</h2>
27 <th width="200">Cost</th>
31 <td>${city.soldiers}</td>
33 <form hx-post="/units">
34 <input type="number" name="amount" size="6" max="${city.population}" hx-trigger="keyup" hx-post="/cost/training" hx-target="#${unit.soldiers.slug}-cost">
35 <input type="hidden" name="type" value="${unit.soldiers.slug}">
36 <button type="submit" ${city.population ? '' : 'disabled'}>Train</button>
39 <td id="${unit.soldiers.slug}-cost"></span>
43 <td>${city.attackers}</td>
45 <form hx-post="/units">
46 <input type="number" name="amount" size="6" max="${city.soldiers}" hx-trigger="keyup" hx-post="/cost/training" hx-target="#${unit.attackers.slug}-cost">
47 <input type="hidden" name="type" value="${unit.attackers.slug}">
48 <button type="submit" ${city.soldiers ? '' : 'disabled'}>Train</button>
51 <td id="${unit.attackers.slug}-cost"></span>
55 <td>${city.defenders}</td>
57 <form hx-post="/units">
58 <input type="number" name="amount" size="6" max="${city.soldiers}" hx-trigger="keyup" hx-post="/cost/training" hx-target="#${unit.defenders.slug}-cost">
59 <input type="hidden" name="type" value="${unit.defenders.slug}">
60 <button type="submit" ${city.soldiers ? '' : 'disabled'}>Train</button>
63 <td id="${unit.defenders.slug}-cost"></td>
66 <th>Special Attackers</th>
67 <td>${city.sp_attackers}</td>
69 <form hx-post="/units">
70 <input type="number" name="amount" size="6" max="${city.attackers}" hx-trigger="keyup" hx-post="/cost/training" hx-target="#${unit.sp_attackers.slug}-cost">
71 <input type="hidden" name="type" value="${unit.sp_attackers.slug}">
72 <button type="submit" ${city.attackers ? '': 'disabled'}>Train</button>
74 <span id="${unit.sp_attackers.slug}-cost"></span>
76 <td id="${unit.sp_attackers.slug}-cost"></td>
79 <th>Special Defenders</th>
80 <td>${city.sp_defenders}</td>
82 <form hx-post="/units">
83 <input type="number" name="amount" size="6" max="${city.defenders}" hx-trigger="keyup" hx-post="/cost/training" hx-target="#${unit.sp_defenders.slug}-cost">
84 <input type="hidden" name="type" value="${unit.sp_defenders.slug}">
85 <button type="submit" ${city.defenders ? '': 'disabled'}>Train</button>
88 <td id="${unit.sp_defenders.slug}-cost"></td>
95 <h2 data-augmented-ui="tl-clip bl-clip none">Training Queues</h2>
99 <th>Amount Expected</th>
102 ${trainingQueues.sort((a, b) => {
103 return a.due - b.due;
105 const created = DateTime.fromMillis(queue.created);
106 const due = DateTime.fromMillis(queue.due);
107 const now = Date.now() - queue.created;
108 const duration = queue.due - queue.created;
112 <td>${queue.display}</td>
113 <td>${queue.amount}</td>
115 <span title="${Math.ceil(due.diff(created).as('minutes')).toLocaleString()} minutes remaining">
116 ${progressBar(now, duration)}<br>
126 return html + queues;