cleaner equipment and modules ui

This commit is contained in:
tresabhi committed 2026-05-17 13:46:53 -05:00
1 parent 26cc0cc723
commit c100a1e655
4 files changed
+45 -17

No files matched your search

@@ -1,11 +1,11 @@
.price { .price {
display: flex; display: flex;
align-items: center;
gap: var(--space-3); gap: var(--space-3);
.entry { .entry {
display: block; display: block;
line-height: 1;
.wrapper { .wrapper {
display: flex; display: flex;
@@ -20,6 +20,12 @@
.slots { .slots {
display: flex; display: flex;
flex-direction: column;
gap: var(--space-2);
align-items: center;
.options {
display: flex;
.slot { .slot {
aspect-ratio: 1 / 1; aspect-ratio: 1 / 1;
@@ -44,6 +50,7 @@
} }
} }
} }
}
.lines { .lines {
display: flex; display: flex;
@@ -53,10 +60,15 @@
.line { .line {
display: flex; display: flex;
align-items: center;
gap: var(--space-3); gap: var(--space-3);
.wrapper {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--space-2);
.stage { .stage {
position: relative; position: relative;
@@ -68,9 +80,7 @@
width: 1em; width: 1em;
height: 1em; height: 1em;
padding: var(--space-3) 0; transform: translate(var(--space-1), var(--space-1));
transform: translate(var(--space-1), calc(-1 * var(--space-1)));
} }
.tier { .tier {
@@ -89,3 +99,4 @@
} }
} }
} }
}
@@ -39,10 +39,7 @@ export function TankopediaLoadout() {
function Equipment() { function Equipment() {
const strings = useStrings(); const strings = useStrings();
const tank = useProtagonist(); const tank = useProtagonist();
const equipment = useEquipment( const equipment = useEquipment(tank.tank!);
tank.tank!.equipment_preset_catalog_id,
tank.tank!.equipment_price_preset_catalog_id,
);
return ( return (
<div className={styles.section}> <div className={styles.section}>
@@ -86,8 +83,14 @@ interface EquipmentSlotProps {
} }
function EquipmentSlot({ slot, rowIndex, columnIndex }: EquipmentSlotProps) { function EquipmentSlot({ slot, rowIndex, columnIndex }: EquipmentSlotProps) {
const equipmentIndex = rowIndex * equipmentColumns + columnIndex;
const tank = useProtagonist();
const equipment = useEquipment(tank.tank!);
const { price } = equipment.price.unlock_slot_prices[equipmentIndex];
return ( return (
<div className={styles.slots}> <div className={styles.slots}>
<div className={styles.options}>
{slot.options_catalog_i_ds.map((id, index) => ( {slot.options_catalog_i_ds.map((id, index) => (
<EquipmentOption <EquipmentOption
key={id} key={id}
@@ -97,6 +100,9 @@ function EquipmentSlot({ slot, rowIndex, columnIndex }: EquipmentSlotProps) {
/> />
))} ))}
</div> </div>
<Price price={price!} />
</div>
); );
} }
@@ -112,11 +118,17 @@ function EquipmentOption({
columnIndex, columnIndex,
}: EquipmentOptionProps) { }: EquipmentOptionProps) {
const equipmentIndex = rowIndex * equipmentColumns + columnIndex; const equipmentIndex = rowIndex * equipmentColumns + columnIndex;
const tank = useProtagonist();
const equipment = useEquipment(tank.tank!);
const isSelected = Tankopedia.use( const isSelected = Tankopedia.use(
(state) => (state) =>
equipmentIndex in state.protagonist.equipment && equipmentIndex in state.protagonist.equipment &&
state.protagonist.equipment[equipmentIndex] === optionIndex, state.protagonist.equipment[equipmentIndex] === optionIndex,
); );
const name =
equipment.preset.slots[equipmentIndex].options_catalog_i_ds[optionIndex];
const equipmentData = equipment.equipments[name];
return ( return (
<Button <Button
@@ -292,11 +304,12 @@ function LineElement({ index, lineName, stage }: LineElementProps) {
} }
return ( return (
<div className={styles.wrapper}>
<Button <Button
className={styles.stage}
color={isSelected ? undefined : "gray"} color={isSelected ? undefined : "gray"}
variant={isSelected ? "surface" : "soft"} variant={isSelected ? "surface" : "soft"}
radius="1" radius="1"
className={styles.stage}
onClick={() => { onClick={() => {
Tankopedia.mutate((draft) => { Tankopedia.mutate((draft) => {
const tankData = tank.tank!; const tankData = tank.tank!;
@@ -338,7 +351,8 @@ function LineElement({ index, lineName, stage }: LineElementProps) {
while (i > 0) { while (i > 0) {
const currentStage = line.stages[i]; const currentStage = line.stages[i];
const valid = currentStage.required_upgrades.every((required) => { const valid = currentStage.required_upgrades.every(
(required) => {
for (const otherLine of tankData.upgrade_lines) { for (const otherLine of tankData.upgrade_lines) {
const idx = draft.protagonist.upgrades[otherLine.name]; const idx = draft.protagonist.upgrades[otherLine.name];
@@ -348,7 +362,8 @@ function LineElement({ index, lineName, stage }: LineElementProps) {
} }
return false; return false;
}); },
);
if (valid) break; if (valid) break;
@@ -371,8 +386,9 @@ function LineElement({ index, lineName, stage }: LineElementProps) {
? strings.tanks.loadout.alternative ? strings.tanks.loadout.alternative
: romanize(stage.number)} : romanize(stage.number)}
</Text> </Text>
</Button>
{price && <Price className={styles.price} price={price} />} {price && <Price className={styles.price} price={price} />}
</Button> </div>
); );
} }
@@ -1,10 +1,11 @@
import type { TankCatalogComponent } from "@protos/blitz_static_tank_component";
import { api } from "../api/dynamic"; import { api } from "../api/dynamic";
import { useAwait } from "./useAwait"; import { useAwait } from "./useAwait";
export function useEquipment(presetId: string, priceId: string) { export function useEquipment(tank: TankCatalogComponent) {
const equipment = useAwait(() => api.equipment(), "equipment"); const equipment = useAwait(() => api.equipment(), "equipment");
const preset = equipment.presets[presetId]; const preset = equipment.presets[tank.equipment_preset_catalog_id];
const price = equipment.prices[priceId]; const price = equipment.prices[tank.equipment_price_preset_catalog_id];
return { preset, price, equipment }; return { preset, price, equipments: equipment.equipments };
} }