ability to cancel construction and have a portion of the funds returned
[browser-rts.git] / src / render / unit-training.ts
index 351bc7930abb364ea7e77d1a71878af3bcf64592..a1bd4b8756bef6a275f1c07b9609229bf510ce90 100644 (file)
@@ -1,9 +1,20 @@
 import _ from "lodash";
 import { CityWithLocation } from "../repository/city";
-import { UnitTrainingQueue } from "../repository/training-queue";
+import { UnitTrainingQueueWithName } from "../repository/training-queue";
 import { Unit } from "../repository/unit";
+import { DateTime } from "luxon";
 
-function progressBar(current, max): string {
+const emptyQueue: UnitTrainingQueueWithName = {
+  display: '',
+  id: '',
+  owner: '',
+  amount: 0,
+  created: 0,
+  due: 0,
+  unit_type: 'empty'
+}
+
+function progressBar(current: number, max: number): string {
     const percent = Math.ceil((current/max) * 100);
     return `
     <div class="progress-bar unit-training" style="background: background: var(--green-bg);
@@ -13,8 +24,11 @@ function progressBar(current, max): string {
     `;
 }
 
-export function renderUnitTraining(city: CityWithLocation, units: Unit[], trainingQueues: UnitTrainingQueue[]): string {
+export function renderUnitTraining(city: CityWithLocation, units: Unit[], trainingQueues: UnitTrainingQueueWithName[]): string {
     const unit = _.keyBy(units, 'slug');
+    const sortedTrainingQueue = trainingQueues.sort((a, b) => {
+        return a.due - b.due;
+    });
     let html = `
     <div hx-trigger="reload-unit-training, every 600s" hx-get="/poll/unit-training">
     <h2 data-augmented-ui="tl-clip bl-clip none">Unit Training</h2>
@@ -27,10 +41,10 @@ export function renderUnitTraining(city: CityWithLocation, units: Unit[], traini
     </tr>
     <tr>
         <th>Soldiers</th>
-        <td>${city.population}</td>
+        <td>${city.soldiers}</td>
         <td>
-            <form hx-post="/units">
-                <input type="number" name="amount" size="6" max="${city.population}" hx-trigger="keyup" hx-post="/cost/training" hx-target="#${unit.soldiers.slug}-cost">
+            <form hx-post="/units" hx-swap="innerHTML" hx-target="#notifications">
+                <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">
                 <input type="hidden" name="type" value="${unit.soldiers.slug}">
                 <button type="submit" ${city.population ? '' : 'disabled'}>Train</button>
             </form>
@@ -39,10 +53,10 @@ export function renderUnitTraining(city: CityWithLocation, units: Unit[], traini
     </tr>
     <tr>
         <th>Attackers</th>
-        <td>${city.soldiers}</td>
+        <td>${city.attackers}</td>
         <td>
-            <form hx-post="/units">
-                <input type="number" name="amount" size="6" max="${city.soldiers}" hx-trigger="keyup" hx-post="/cost/training" hx-target="#${unit.attackers.slug}-cost">
+            <form hx-post="/units" hx-swap="innerHTML" hx-target="#notifications">
+                <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">
                 <input type="hidden" name="type" value="${unit.attackers.slug}">
                 <button type="submit" ${city.soldiers ? '' : 'disabled'}>Train</button>
             </form>
@@ -51,10 +65,10 @@ export function renderUnitTraining(city: CityWithLocation, units: Unit[], traini
     </tr>
     <tr>
         <th>Defenders</th>
-        <td>${city.soldiers}</td>
+        <td>${city.defenders}</td>
         <td>
-            <form hx-post="/units">
-                <input type="number" name="amount" size="6" max="${city.soldiers}" hx-trigger="keyup" hx-post="/cost/training" hx-target="#${unit.defenders.slug}-cost">
+            <form hx-post="/units" hx-swap="innerHTML" hx-target="#notifications">
+                <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">
                 <input type="hidden" name="type" value="${unit.defenders.slug}">
                 <button type="submit" ${city.soldiers ? '' : 'disabled'}>Train</button>
             </form>
@@ -63,10 +77,10 @@ export function renderUnitTraining(city: CityWithLocation, units: Unit[], traini
     </tr>
     <tr>
         <th>Special Attackers</th>
-        <td>${city.attackers}</td>
+        <td>${city.sp_attackers}</td>
         <td>
-            <form hx-post="/units">
-                <input type="number" name="amount" size="6" max="${city.attackers}" hx-trigger="keyup" hx-post="/cost/training" hx-target="#${unit.sp_attackers.slug}-cost">
+            <form hx-post="/units" hx-swap="innerHTML" hx-target="#notifications">
+                <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">
                 <input type="hidden" name="type" value="${unit.sp_attackers.slug}">
                 <button type="submit" ${city.attackers ? '': 'disabled'}>Train</button>
             </form>
@@ -76,10 +90,10 @@ export function renderUnitTraining(city: CityWithLocation, units: Unit[], traini
     </tr>
     <tr>
         <th>Special Defenders</th>
-        <td>${city.defenders}</td>
+        <td>${city.sp_defenders}</td>
         <td>
-            <form hx-post="/units">
-                <input type="number" name="amount" size="6" max="${city.defenders}" hx-trigger="keyup" hx-post="/cost/training" hx-target="#${unit.sp_defenders.slug}-cost">
+            <form hx-post="/units" hx-swap="innerHTML" hx-target="#notifications">
+                <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">
                 <input type="hidden" name="type" value="${unit.sp_defenders.slug}">
                 <button type="submit" ${city.defenders ? '': 'disabled'}>Train</button>
             </form>
@@ -89,28 +103,46 @@ export function renderUnitTraining(city: CityWithLocation, units: Unit[], traini
     </table>
     `;
 
+    const finalTrainingQueue = sortedTrainingQueue;
+    if(finalTrainingQueue.length < city.max_training_queue) {
+      while(finalTrainingQueue.length < city.max_construction_queue) {
+        finalTrainingQueue.push(emptyQueue);
+      }
+    }
+
     const queues = `
     <hr>
     <h2 data-augmented-ui="tl-clip bl-clip none">Training Queues</h2>
     <table>
     <tr>
-    <th>Unit Type</th>
-    <th>Amount Expected</th>
+    <th align="left">Unit Type</th>
+    <th align="left">Amount Expected</th>
     <th>Progress</th>
     </tr>
-    ${trainingQueues.sort((a, b) => {
-        return a.due - b.due;
-    }).map(queue => {
+    ${sortedTrainingQueue.map(queue => {
+      if(queue.unit_type === 'empty') {
+        return `<tr>
+        <td colspan="4">You have sufficient queue capacity to train more units.</td>
+        </tr>`;
+      }
+      else {
+        const created = DateTime.fromMillis(queue.created);
+        const due = DateTime.fromMillis(queue.due);
         const now = Date.now() - queue.created;
         const duration = queue.due - queue.created;
 
         return `
         <tr>
-        <td>${queue.unit_type}</td>
+        <td>${queue.display}</td>
         <td>${queue.amount}</td>
-        <td>${progressBar(now, duration)}</td>
+        <td>
+        <span title="${Math.ceil(due.diff(created).as('minutes')).toLocaleString()} minutes remaining">
+        ${progressBar(now, duration)}<br>
+        </span>
+        </td>
         </tr>
         `;
+      }
     }).join("\n")}
     </table>
     </div>