fix(store, inventory): improve display of requirements
authorxangelo <me@xangelo.ca>
Mon, 25 Nov 2024 18:53:01 +0000 (13:53 -0500)
committerxangelo <me@xangelo.ca>
Mon, 25 Nov 2024 18:53:01 +0000 (13:53 -0500)
public/assets/css/store.css
public/assets/css/tabs.css
src/server/views/components/stats.ts
src/server/views/inventory.ts
src/server/views/stores.ts

index 9a546e410c53697bb90e7b54dd18afb3c3933283..bbbcd1be05791997af3c7b3bed8a9d5f0b4dcf9d 100644 (file)
@@ -24,5 +24,9 @@
             color: #6d251c;
             grid-column: 1 / -1;
         }
+
+        .requirement-title::after {
+            content: ': ';
+        }
     }
 }
\ No newline at end of file
index 0789a224bcb8c87cea1137d4d8db4a31843547f5..7a7ba44a93a6ffa27b23defb0e8f7389537e9527 100644 (file)
 nav {
-    text-align: center;
-    padding: 1rem 0;
+  text-align: center;
+  padding: 1rem 0;
 
-    li {
-        display: inline-block;
-        list-style: none;
+  li {
+    display: inline-block;
+    list-style: none;
 
-        &:before {
-            content: '[';
-        }
+    &:before {
+      content: '[';
+    }
 
-        &:after {
-            content: ']';
-        }
+    &:after {
+      content: ']';
     }
+  }
 
-    a {
-        text-decoration: none;
+  a {
+    text-decoration: none;
 
-        &.active {
-            font-weight: bold;
-            text-decoration: underline;
-        }
+    &.active {
+      font-weight: bold;
+      text-decoration: underline;
     }
+  }
 
-    &.filter {
-        margin: 0;
-        text-align: right;
-        border: 0;
-        padding: 0;
-        position: relative;
-        bottom: 5px;
-
-        a {
-            border-bottom-width: 0;
-            z-index: 1;
-            padding: 0.6rem;
-            position: relative;
-
-            &.active {
-                background-color: #fff;
-                border: solid #6d251c;
-                border-width: 1px 1px 0;
-                z-index: 4;
-            }
-        }
+  &.filter {
+    margin: 0;
+    text-align: right;
+    border: 0;
+    padding: 0;
+    position: relative;
+    bottom: 5px;
+
+    a {
+      border-bottom-width: 0;
+      z-index: 1;
+      padding: 0.6rem;
+      position: relative;
+
+      &.active {
+        background-color: #fff;
+        border: solid #6d251c;
+        border-width: 1px 1px 0;
+        z-index: 4;
+      }
     }
+  }
 
 }
 
 .filter-container {
-    .listing {
-        border: solid 1px #6d251c;
-        z-index: 2;
-        position: relative;
-        background-color: #fff;
-        max-height: 400px;
-        width: 100%;
-        overflow: auto;
+  .listing {
+    border: solid 1px #6d251c;
+    z-index: 2;
+    position: relative;
+    background-color: #fff;
+    max-height: 400px;
+    width: 100%;
+    overflow: auto;
 
-        .filter-result {
-            display: none;
+    .filter-result {
+      display: none;
 
-            &.active {
-                display: block !important;
-            }
-        }
+      &.active {
+        display: block !important;
+      }
     }
+  }
 }
 
 #main-nav {
-    margin-bottom: 1rem;
-    position: relative;
+  margin-bottom: 1rem;
+  position: relative;
 
-    section {
-        min-height: 344px;
-    }
+  section {
+    min-height: 344px;
+  }
 }
 
 .tab {
-    display: none;
+  display: none;
 
-    &.active {
-        display: block;
-    }
+  &.active {
+    display: block;
+  }
 }
 
 
 .list-item {
-    display: flex;
-    text-align: left;
-    padding: 0.5rem;
-    overflow: hidden;
+  display: flex;
+  text-align: left;
+  padding: 0.5rem;
+  overflow: hidden;
 
-    &:nth-child(even) {
-        background-color: #f2f0ec;
-    }
+  &:nth-child(even) {
+    background-color: #f2f0ec;
+  }
 
-    .icon-wrapper {
-        position: relative;
-        margin-right: 0.5rem;
-        width: 77px;
-
-        .icon {
-            width: 64px;
-            height: 64px;
-            padding: 0;
-            background-repeat: no-repeat;
-            background-size: contain;
-            position: relative;
-            border: solid 1px #6d251c;
-            box-sizing: border-box;
-        }
+  .icon-wrapper {
+    position: relative;
+    margin-right: 0.5rem;
+    width: 77px;
+
+    .icon {
+      width: 64px;
+      height: 64px;
+      padding: 0;
+      background-repeat: no-repeat;
+      background-size: contain;
+      position: relative;
+      border: solid 1px #6d251c;
+      box-sizing: border-box;
+    }
 
-        .actions {
-            margin-top: 0.2rem;
+    .actions {
+      margin-top: 0.2rem;
 
-            button {
-                width: 100%;
-                font-size: 0.7rem;
-                padding: 0.3rem 0.5rem;
-            }
+      button {
+        width: 100%;
+        font-size: 0.7rem;
+        padding: 0.3rem 0.5rem;
+      }
 
-        }
     }
+  }
 
 
-    .details {
-        padding: 0 0.4rem;
-        line-height: 1rem;
-        flex-grow: 2;
-        width: 100%;
+  .details {
+    padding: 0 0.4rem;
+    line-height: 1rem;
+    flex-grow: 2;
+    width: 100%;
 
-        &>div {
-            margin-bottom: 4px;
-        }
+    &>div {
+      margin-bottom: 4px;
+    }
 
-        .name {
-            font-weight: bold;
-            background: linear-gradient(90deg, #ecd4a8 0%, transparent 40%);
-            border-bottom: 2px solid #6d251c;
-            padding: 4px;
-            font-size: 0.9rem;
-        }
+    .name {
+      font-weight: bold;
+      background: linear-gradient(90deg, #ecd4a8 0%, transparent 40%);
+      border-bottom: 2px solid #6d251c;
+      padding: 4px;
+      font-size: 0.9rem;
+    }
 
-        .stat-mods {
-            font-size: 0.8rem;
-            display: grid;
-            grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
-            gap: 0.2rem;
+    .stat-mods {
+      font-size: 0.8rem;
+      display: grid;
+      grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
+      gap: 0.2rem;
+      margin: 0.5rem 0;
+
+      .requirement {
+        display: grid;
+        grid-template-columns: auto 1fr;
+        gap: 0.2rem;
+        border: solid 1px #b19e81;
+        font-size: 0.7rem;
+
+        .requirement-title {
+          text-transform: uppercase;
+          background-color: #e2d6c3;
+          border-right: solid 1px #b19e81;
+          padding: 0.1rem 0.2rem;
+          width: 35px;
+          text-align: center;
         }
 
-        .requirements {
-            font-size: 0.8rem;
-            display: grid;
-            grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
-            gap: 0.2rem;
-
-            .requirement-title {
-                font-weight: bold;
-                text-transform: capitalize;
-            }
+        .requirement-value {
+          padding: 0.1rem;
+          background-color: #fefbf4;
         }
+      }
+    }
 
+    .requirements {
+      font-size: 0.8rem;
+      display: grid;
+      grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
+      gap: 0.2rem;
 
+      .requirement-title {
+        font-weight: bold;
+        text-transform: capitalize;
+      }
     }
-
+  }
 }
\ No newline at end of file
index 61c3a1e7116fd3c8cec38cc559d631f8b34ecf6f..116defa965034cab0784efbfd4e212f6bfc987bc 100644 (file)
@@ -16,6 +16,5 @@ export function renderStatBoostWithPlayerIncrease(player: Player, name: ItemStat
   const diff = effectiveDamage - val;
 
   // calculate any stat boost from the player
-  return `<div class="requirement"><span class="requirement-title">${name}</span>: 
-<span class="requirement-value tooltip ${typeof val === 'number' ? (val > 0 ? "success": "error") : ""}" title="${val}(item) + ${diff}(from stats)">${valSign}${effectiveDamage}</span></div>`;
+  return `<div class="requirement"><span class="requirement-title">${name}</span><span class="requirement-value tooltip ${typeof val === 'number' ? (val > 0 ? "success": "error") : ""}" title="${val}(item) + ${diff}(from stats)">${valSign}${effectiveDamage}</span></div>`;
 }
index 1cd533f66c1c979ca65d51f44ba8467a67523b56..41857e54b5a9ff709431011e4e7a9a18b0ec277a 100644 (file)
@@ -96,7 +96,7 @@ function renderStatBoost(name: string, val: number | string, percent: boolean =
   if(typeof val === 'number') {
     valSign = val > 0 ? '+' : '-';
   }
-  return `<div class="requirement"><span class="requirement-title">${name}</span><span class="requirement-value ${typeof val === 'number' ? (val > 0 ? "success": "error") : ""}">${valSign}${val}${percent ? '%' : ''}</span></div>`;
+  return `<div class="requirement"><span class="requirement-title">${name}</span><span class="requirement-value ${typeof val === 'number' ? (val > 0 ? "success": "error") : ""}">${valSign}${val}${percent ? '%' : ''}</span></div>`;
 }
 
 function renderInventoryItem(player: Player, item: EquippedItemDetails , action: (item: EquippedItemDetails) => string): string {
index 33413ffebc372cdbae87dea50f0cc2d15bbf1f8e..6b68bd7e818cb73ad3d81473d809cbd2f2a55543 100644 (file)
@@ -20,7 +20,7 @@ function renderStat(title: string, display: string, val: any, options?: RenderSt
     valSign = val > 0 ? '+' : '-';
   }
 
-  return `<span title="${title}"><span class="requirement-title">${display}</span>: <span class="requirement-value ${opts.unsigned ? '' : (val > 0 ? "success": "error")}">${opts.unsigned ? val : `${valSign}${val}`}</span></span>`;
+  return `<div class="requirement" title="${title}"><span class="requirement-title">${display}</span><span class="requirement-value ${opts.unsigned ? '' : (val > 0 ? "success": "error")}">${opts.unsigned ? val : `${valSign}${val}`}</span></div>`;
 }
 
 function renderStatBoost(name: ItemStatBoostAbbr, val: number | string, title?: string): string {
@@ -28,7 +28,7 @@ function renderStatBoost(name: ItemStatBoostAbbr, val: number | string, title?:
   if(typeof val === 'number') {
     valSign = val > 0 ? '+' : '-';
   }
-  return `<div class="requirement"><span class="requirement-title" title="${title}">${name}</span><span class="requirement-value ${typeof val === 'number' ? (val > 0 ? "success": "error") : ""}">${valSign}${val}</span></div>`;
+  return `<div class="requirement"><span class="requirement-title" title="${title}">${name}</span><span class="requirement-value ${typeof val === 'number' ? (val > 0 ? "success": "error") : ""}">${valSign}${val}</span></div>`;
 }
 
 function renderRequirement(name: string, val: number | string, currentVal?: number): string {
@@ -36,7 +36,7 @@ function renderRequirement(name: string, val: number | string, currentVal?: numb
   if (currentVal && typeof val === 'number') {
     colorIndicator = currentVal >= val ? 'success' : 'error';
   }
-  return `<div class="requirement"><span class="requirement-title">${name}</span><span class="requirement-value ${colorIndicator}">${val.toLocaleString()}</span></div>`;
+  return `<div class="requirement"><span class="requirement-title">${name}</span><span class="requirement-value ${colorIndicator}">${val.toLocaleString()}</span></div>`;
 }
 
 function renderShopItem(item: (ShopItem & Item), action: (item: (ShopItem & Item)) => string): string {
@@ -61,7 +61,9 @@ export function renderEquipmentDetails(item: ShopEquipment, player: Player): str
 
   return `
     <div class="details">
-      <div class="name">${item.name}${item.equipment_slot === 'TWO_HANDED' ? ' (2H)': ''}</div>
+      <div class="name">${item.name}${item.equipment_slot === 'TWO_HANDED' ? ' (2H)': ''}
+        <span class="right store-cost">${item.cost.toLocaleString()}G</span>
+      </div>
       <div class="stat-mods">
       ${item.boosts.defence ? renderStatBoost('DEF', item.boosts.defence) : ''}
       ${item.boosts.strength ? renderStatBoost('STR', item.boosts.strength) : ''}
@@ -72,7 +74,6 @@ export function renderEquipmentDetails(item: ShopEquipment, player: Player): str
       ${item.boosts.damage_mitigation ? renderStatBoost('MIT', item.boosts.damage_mitigation.toString())+'%' : ''}
       ${renderStat(isSpell ? 'Uses': 'Durability', isSpell ? 'Uses': 'DUR', item.maxAp, { unsigned: true })}
       </div>
-      ${item.hasOwnProperty('id') ? `<div class="store-cost">${item.cost.toLocaleString()}G</div>` : ''}
       <div class="requirements">
       ${item.requirements.level ? renderRequirement('LVL', item.requirements.level, player.level): ''}
       ${item.requirements.strength ? renderRequirement('STR', item.requirements.strength, player.strength): ''}