display error when cant build something
[browser-rts.git] / src / render / unit-training.ts
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";
6
7 function progressBar(current: number, max: number): string {
8     const percent = Math.ceil((current/max) * 100);
9     return `
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);">
12     ${percent}%
13     </div>
14     `;
15 }
16
17 export function renderUnitTraining(city: CityWithLocation, units: Unit[], trainingQueues: UnitTrainingQueueWithName[]): string {
18     const unit = _.keyBy(units, 'slug');
19     let html = `
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>
22     <table>
23     <tr>
24         <th>Unit</th>
25         <th>Avail.</td>
26         <th></th>
27         <th width="200">Cost</th>
28     </tr>
29     <tr>
30         <th>Soldiers</th>
31         <td>${city.soldiers}</td>
32         <td>
33             <form hx-post="/units" hx-swap="innerHTML" hx-target="#notifications">
34                 <input type="number" name="amount" size="6" max="${city.population}" hx-trigger="keyup" hx-post="/cost/training" hx-target="#${unit.soldiers.slug}-cost" hx-swap="innerHTML">
35                 <input type="hidden" name="type" value="${unit.soldiers.slug}">
36                 <button type="submit" ${city.population ? '' : 'disabled'}>Train</button>
37             </form>
38         </td>
39         <td id="${unit.soldiers.slug}-cost"></span>
40     </tr>
41     <tr>
42         <th>Attackers</th>
43         <td>${city.attackers}</td>
44         <td>
45             <form hx-post="/units" hx-swap="innerHTML" hx-target="#notifications">
46                 <input type="number" name="amount" size="6" max="${city.soldiers}" hx-trigger="keyup" hx-post="/cost/training" hx-target="#${unit.attackers.slug}-cost" hx-swap="innerHTML">
47                 <input type="hidden" name="type" value="${unit.attackers.slug}">
48                 <button type="submit" ${city.soldiers ? '' : 'disabled'}>Train</button>
49             </form>
50         </td>
51         <td id="${unit.attackers.slug}-cost"></span>
52     </tr>
53     <tr>
54         <th>Defenders</th>
55         <td>${city.defenders}</td>
56         <td>
57             <form hx-post="/units" hx-swap="innerHTML" hx-target="#notifications">
58                 <input type="number" name="amount" size="6" max="${city.soldiers}" hx-trigger="keyup" hx-post="/cost/training" hx-target="#${unit.defenders.slug}-cost" hx-swap="innerHTML">
59                 <input type="hidden" name="type" value="${unit.defenders.slug}">
60                 <button type="submit" ${city.soldiers ? '' : 'disabled'}>Train</button>
61             </form>
62         </td>
63         <td id="${unit.defenders.slug}-cost"></td>
64     </tr>
65     <tr>
66         <th>Special Attackers</th>
67         <td>${city.sp_attackers}</td>
68         <td>
69             <form hx-post="/units" hx-swap="innerHTML" hx-target="#notifications">
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" hx-swap="innerHTML">
71                 <input type="hidden" name="type" value="${unit.sp_attackers.slug}">
72                 <button type="submit" ${city.attackers ? '': 'disabled'}>Train</button>
73             </form>
74             <span id="${unit.sp_attackers.slug}-cost"></span>
75         </td>
76         <td id="${unit.sp_attackers.slug}-cost"></td>
77     </tr>
78     <tr>
79         <th>Special Defenders</th>
80         <td>${city.sp_defenders}</td>
81         <td>
82             <form hx-post="/units" hx-swap="innerHTML" hx-target="#notifications">
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" hx-swap="innerHTML">
84                 <input type="hidden" name="type" value="${unit.sp_defenders.slug}">
85                 <button type="submit" ${city.defenders ? '': 'disabled'}>Train</button>
86             </form>
87         </td>
88         <td id="${unit.sp_defenders.slug}-cost"></td>
89         </tr>
90     </table>
91     `;
92
93     const queues = `
94     <hr>
95     <h2 data-augmented-ui="tl-clip bl-clip none">Training Queues</h2>
96     <table>
97     <tr>
98     <th>Unit Type</th>
99     <th>Amount Expected</th>
100     <th>Progress</th>
101     </tr>
102     ${trainingQueues.sort((a, b) => {
103         return a.due - b.due;
104     }).map(queue => {
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;
109
110       return `
111       <tr>
112       <td>${queue.display}</td>
113       <td>${queue.amount}</td>
114       <td>
115       <span title="${Math.ceil(due.diff(created).as('minutes')).toLocaleString()} minutes remaining">
116       ${progressBar(now, duration)}<br>
117       </span>
118       </td>
119       </tr>
120       `;
121     }).join("\n")}
122     </table>
123     </div>
124     `;
125
126     return html + queues;
127 }