From d2b4cc3e7d71bc7dd8de98121578589e6b4669c8 Mon Sep 17 00:00:00 2001 From: tresabhi <43380238+tresabhi@users.noreply.github.com> Date: Thu, 28 May 2026 13:14:38 -0500 Subject: [PATCH] consumable prices --- packages/i18n/strings/en.json | 4 + .../website-ue/src/components/Price/index.tsx | 26 +++-- .../TankopediaLoadout/index.module.css | 35 +++--- .../components/TankopediaLoadout/index.tsx | 110 +++++++++++------- 4 files changed, 113 insertions(+), 62 deletions(-) diff --git a/packages/i18n/strings/en.json b/packages/i18n/strings/en.json index efc5aae71..3aa611c5d 100644 --- a/packages/i18n/strings/en.json +++ b/packages/i18n/strings/en.json @@ -1,4 +1,8 @@ { + "price": { + "free": "Free" + }, + "nations": { "0": "Unspecified", "1": "USSR", diff --git a/packages/website-ue/src/components/Price/index.tsx b/packages/website-ue/src/components/Price/index.tsx index b7f6a86e9..0bc72ccda 100644 --- a/packages/website-ue/src/components/Price/index.tsx +++ b/packages/website-ue/src/components/Price/index.tsx @@ -6,23 +6,35 @@ import { useLocale } from "../../hooks/useLocale"; import { classNames } from "../../ui/classNames"; import { Text } from "../Text"; import styles from "./index.module.css"; +import { useStrings } from "../../hooks/useStrings"; interface PriceProps extends ComponentProps<"div"> { - price: StandardPrice; + price?: StandardPrice; } export function Price({ price, className, ...props }: PriceProps) { + const strings = useStrings(); + const normalized = + price === undefined + ? [] + : price.price_list.filter( + (entry) => + entry.currency_price === undefined || + entry.currency_price.amount !== 0, + ); + return (
- {price.price_list.map((entry, index) => ( + {normalized.map((entry, index) => ( ))} - {price.price_list.length === 0 && ( - - Free - - )} + {price === undefined || + (normalized.length === 0 && ( + + {strings.price.free} + + ))}
); } diff --git a/packages/website-ue/src/components/TankopediaLoadout/index.module.css b/packages/website-ue/src/components/TankopediaLoadout/index.module.css index 336a2e674..1ca654c48 100644 --- a/packages/website-ue/src/components/TankopediaLoadout/index.module.css +++ b/packages/website-ue/src/components/TankopediaLoadout/index.module.css @@ -18,25 +18,32 @@ grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); - .consumable { - font-size: var(--space-5); + .consumable-wrapper { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--space-2); - img { - width: 1em; - height: 1em; - } + .consumable { + font-size: var(--space-5); - .info { - display: flex; - flex-direction: column; + img { + width: 1em; + height: 1em; + } - .entry { + .info { display: flex; - gap: var(--space-2); + flex-direction: column; - svg { - width: 1em; - height: 1em; + .entry { + display: flex; + gap: var(--space-2); + + svg { + width: 1em; + height: 1em; + } } } } diff --git a/packages/website-ue/src/components/TankopediaLoadout/index.tsx b/packages/website-ue/src/components/TankopediaLoadout/index.tsx index cc316fa9c..34f7ec1a0 100644 --- a/packages/website-ue/src/components/TankopediaLoadout/index.tsx +++ b/packages/website-ue/src/components/TankopediaLoadout/index.tsx @@ -43,6 +43,7 @@ import { TankopediaCollapsible } from "../TankopediaCollapsible"; import type { ConsumableComponent } from "@protos/blitz_static_consumable_component"; import { Tank } from "@protos/tank"; import { select } from "three/src/nodes/math/ConditionalNode.js"; +import type { BlitzStaticPurchaseComponent } from "@protos/blitz_static_purchase_component"; interface TankopediaLoadoutProps { characteristics: ComputedCharacteristics; @@ -95,7 +96,13 @@ function Consumables({ characteristics }: ConsumablesProps) { {Object.entries(consumables.consumables).map( ([id, { compatibility, consumable, purchase }]) => { if (!isCompatible(compatibility!)) return null; - return ; + return ( + + ); }, )} @@ -106,51 +113,72 @@ function Consumables({ characteristics }: ConsumablesProps) { interface ConsumableProps { id: string; consumable: ConsumableComponent; + purchase: BlitzStaticPurchaseComponent; } -function Consumable({ id, consumable }: ConsumableProps) { +function Consumable({ id, consumable, purchase }: ConsumableProps) { const gameStrings = useGameStrings("ConsumableEntity"); const isSelected = Tankopedia.use((state) => state.protagonist.consumables.includes(id), ); + const tank = useProtagonist(); + const tierPrices = useTierPrices(); + + const price = useMemo(() => { + const { prices } = tierPrices.prices[purchase.price_per_tier_catalog_id]; + + for (const { tier_catalog_id, unlock_price } of prices) { + if (tier_catalog_id === tank.tank!.tier_catalog_id) { + return unlock_price; + } + } + + throw new Error( + `No price found for tier catalog id ${tank.tank!.tier_catalog_id}`, + ); + }, [tank.id, purchase.price_per_tier_catalog_id]); return ( - - - + +
+ + 10s +
+
+ + + + + + ); } @@ -484,8 +512,8 @@ function LineElement({ index, lineName, stage }: LineElementProps) { } return ( - -
+
+ + - {} -
- + {} +
); }