refine layout

This commit is contained in:
tresabhi committed 2026-05-28 14:13:19 -05:00
1 parent 0a186399b6
commit d9b22431fa
10 files changed
+45 -128

No files matched your search

@@ -1,19 +1,11 @@
.characteristics { .characteristics {
padding: var(--space-5); padding: var(--space-5);
padding-top: var(--space-6);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--space-5); gap: var(--space-5);
box-sizing: border-box; box-sizing: border-box;
max-height: 100%;
overflow-y: auto;
&[data-visible="false"] {
display: none;
}
.group { .group {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -1,21 +1,17 @@
import { CaretDownIcon, CaretRightIcon } from "@radix-ui/react-icons"; import { CaretDownIcon, CaretRightIcon } from "@radix-ui/react-icons";
import { useStrings } from "../../hooks/useStrings";
import { Tankopedia } from "../../stores/tankopedia";
import { import {
characteristicsOrder, characteristicsOrder,
type CharacteristicRenderConfig, type CharacteristicRenderConfig,
type CharacteristicsGroup, type CharacteristicsGroup,
} from "../../tankopedia/characteristicsOrder"; } from "../../tankopedia/characteristicsOrder";
import styles from "./index.module.css";
import { Heading } from "../Heading"; import { Heading } from "../Heading";
import { Tankopedia, TankopediaTab } from "../../stores/tankopedia"; import styles from "./index.module.css";
import { useStrings } from "../../hooks/useStrings";
export function TankopediaCharacteristics() { export function TankopediaCharacteristics() {
const isVisible = Tankopedia.use(
(state) => state.tab === TankopediaTab.Characteristics,
);
return ( return (
<div className={styles.characteristics} data-visible={isVisible}> <div className={styles.characteristics}>
{characteristicsOrder.map((group) => ( {characteristicsOrder.map((group) => (
<Group {...group} /> <Group {...group} />
))} ))}
@@ -1,5 +1,7 @@
import { romanize } from "@blitzkit/core"; import { romanize } from "@blitzkit/core";
import type { ConsumableComponent } from "@protos/blitz_static_consumable_component";
import type { BlitzStaticEquipmentPresetComponent_EquipmentSlot } from "@protos/blitz_static_equipment_preset_component"; import type { BlitzStaticEquipmentPresetComponent_EquipmentSlot } from "@protos/blitz_static_equipment_preset_component";
import type { BlitzStaticPurchaseComponent } from "@protos/blitz_static_purchase_component";
import { Grade } from "@protos/blitz_static_standard_grades_enum"; import { Grade } from "@protos/blitz_static_standard_grades_enum";
import { StandardPrice } from "@protos/blitz_static_standard_price"; import { StandardPrice } from "@protos/blitz_static_standard_price";
import type { UpgradeLine } from "@protos/blitz_static_tank_upgrade_line"; import type { UpgradeLine } from "@protos/blitz_static_tank_upgrade_line";
@@ -24,26 +26,20 @@ import {
import { useCompatibility } from "../../hooks/useCompatibility"; import { useCompatibility } from "../../hooks/useCompatibility";
import { useConsumables } from "../../hooks/useConsumables"; import { useConsumables } from "../../hooks/useConsumables";
import { useEquipment } from "../../hooks/useEquipment"; import { useEquipment } from "../../hooks/useEquipment";
import { useGameStrings } from "../../hooks/useGameStrings";
import { useProtagonist } from "../../hooks/useProtagonist"; import { useProtagonist } from "../../hooks/useProtagonist";
import { useStrings } from "../../hooks/useStrings"; import { useStrings } from "../../hooks/useStrings";
import { useTierPrices } from "../../hooks/useTierPrices"; import { useTierPrices } from "../../hooks/useTierPrices";
import { useUpgradePreset } from "../../hooks/useUpgradePreset"; import { useUpgradePreset } from "../../hooks/useUpgradePreset";
import { Tankopedia, TankopediaCompare } from "../../stores/tankopedia"; import { Tankopedia } from "../../stores/tankopedia";
import type { ComputedCharacteristics } from "../../tankopedia/computeCharacteristics";
import { Button } from "../Button"; import { Button } from "../Button";
import { Heading } from "../Heading"; import { Heading } from "../Heading";
import { IconButton } from "../IconButton"; import { IconButton } from "../IconButton";
import { Price } from "../Price"; import { Price } from "../Price";
import { Section } from "../Section";
import { Text } from "../Text"; import { Text } from "../Text";
import styles from "./index.module.css";
import type { ComputedCharacteristics } from "../../tankopedia/computeCharacteristics";
import { Tooltip } from "../Tooltip"; import { Tooltip } from "../Tooltip";
import { useGameStrings } from "../../hooks/useGameStrings"; import styles from "./index.module.css";
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 { interface TankopediaLoadoutProps {
characteristics: ComputedCharacteristics; characteristics: ComputedCharacteristics;
@@ -1,20 +0,0 @@
.tabs {
display: flex;
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
.tab {
padding: var(--space-3) var(--space-5);
border-top: var(--space-2) solid transparent;
cursor: pointer;
&[data-selected="true"] {
background: linear-gradient(var(--accent-a4), transparent);
border-top: var(--space-2) solid var(--accent-9);
}
}
}
@@ -1,37 +0,0 @@
import { useStrings } from "../../hooks/useStrings";
import { Tankopedia, TankopediaTab } from "../../stores/tankopedia";
import { Text } from "../Text";
import styles from "./index.module.css";
export function TankopediaNavigation() {
const strings = useStrings();
const tab = Tankopedia.use((state) => state.tab);
return (
<div className={styles.tabs}>
<div
className={styles.tab}
data-selected={tab === TankopediaTab.Tank}
onClick={() => {
Tankopedia.mutate((draft) => {
draft.tab = TankopediaTab.Tank;
});
}}
>
<Text>{strings.tanks.navigation.tank}</Text>
</div>
<div
className={styles.tab}
data-selected={tab === TankopediaTab.Characteristics}
onClick={() => {
Tankopedia.mutate((draft) => {
draft.tab = TankopediaTab.Characteristics;
});
}}
>
<Text>{strings.tanks.navigation.characteristics}</Text>
</div>
</div>
);
}
@@ -1,11 +1,12 @@
.sandbox { .wrapper {
position: absolute; height: calc(100dvh - 16rem);
top: 0; position: relative;
left: 0;
width: 100%;
height: 100%;
&[data-visible="false"] { .sandbox {
display: none; position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
} }
} }
@@ -1,22 +1,21 @@
import { Canvas, useLoader } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei"; import { OrbitControls } from "@react-three/drei";
import styles from "./index.module.css"; import { Canvas, useLoader } from "@react-three/fiber";
import { GLTFLoader } from "three-stdlib"; import { GLTFLoader } from "three-stdlib";
import { Tankopedia } from "../../stores/tankopedia"; import styles from "./index.module.css";
import { TankopediaTab } from "../../stores/tankopedia";
export function TankopediaSandbox() { export function TankopediaSandbox() {
const isVisible = Tankopedia.use((state) => state.tab === TankopediaTab.Tank);
return ( return (
<div className={styles.sandbox} data-visible={isVisible}> <div className={styles.wrapper}>
<Canvas <div className={styles.sandbox}>
shadows <Canvas
className={styles.canvas} // scene={{ fog: new Fog("black", 15, 40) }}
frameloop={isVisible ? "always" : "never"} shadows
> className={styles.canvas}
{!import.meta.env.SSR && <Content />} frameloop="demand"
</Canvas> >
{!import.meta.env.SSR && <Content />}
</Canvas>
</div>
</div> </div>
); );
} }
@@ -34,8 +33,8 @@ function Content() {
<pointLight castShadow position={[3, 10, 5]} intensity={1000} /> <pointLight castShadow position={[3, 10, 5]} intensity={1000} />
<mesh receiveShadow position={[0, -1, 0]} rotation={[-Math.PI / 2, 0, 0]}> <mesh receiveShadow position={[0, -1, 0]} rotation={[-Math.PI / 2, 0, 0]}>
<planeGeometry args={[30, 30]} /> <planeGeometry args={[2 ** 8, 2 ** 8]} />
<meshStandardMaterial color="green" /> <meshStandardMaterial color="black" />
</mesh> </mesh>
<OrbitControls /> <OrbitControls />
@@ -4,13 +4,12 @@
display: flex; display: flex;
.sandbox { .sandbox {
position: relative;
flex-grow: 1; flex-grow: 1;
background-color: black;
overflow-y: auto;
} }
.stats { .loadout {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -18,5 +17,7 @@
padding: var(--space-5); padding: var(--space-5);
overflow-y: auto; overflow-y: auto;
background-color: var(--gray-2);
} }
} }
@@ -1,6 +1,8 @@
import { Fragment, useMemo } from "react"; import { Fragment, useMemo } from "react";
import { api } from "../../../../api/dynamic"; import { api } from "../../../../api/dynamic";
import { TankopediaCharacteristics } from "../../../../components/TankopediaCharacteristics";
import { TankopediaLoadout } from "../../../../components/TankopediaLoadout"; import { TankopediaLoadout } from "../../../../components/TankopediaLoadout";
import { TankopediaSandbox } from "../../../../components/TankopediaSandbox";
import { withErrorWrapper } from "../../../../hocs/withErrorWrapper"; import { withErrorWrapper } from "../../../../hocs/withErrorWrapper";
import { withLocale } from "../../../../hocs/withLocale"; import { withLocale } from "../../../../hocs/withLocale";
import { useAwait } from "../../../../hooks/useAwait"; import { useAwait } from "../../../../hooks/useAwait";
@@ -10,9 +12,6 @@ import { Tankopedia } from "../../../../stores/tankopedia";
import { characteristicsOrder } from "../../../../tankopedia/characteristicsOrder"; import { characteristicsOrder } from "../../../../tankopedia/characteristicsOrder";
import { computeCharacteristics } from "../../../../tankopedia/computeCharacteristics"; import { computeCharacteristics } from "../../../../tankopedia/computeCharacteristics";
import styles from "./_index.module.css"; import styles from "./_index.module.css";
import { TankopediaSandbox } from "../../../../components/TankopediaSandbox";
import { TankopediaNavigation } from "../../../../components/TankopediaNavigation";
import { TankopediaCharacteristics } from "../../../../components/TankopediaCharacteristics";
interface PageProps { interface PageProps {
id: string; id: string;
@@ -24,8 +23,6 @@ export const Page = withErrorWrapper(
Tankopedia.useInitialization(protagonistTank); Tankopedia.useInitialization(protagonistTank);
// const renderCharacteristic = useCharacteristicRenderer();
const protagonist = Tankopedia.use((state) => state.protagonist); const protagonist = Tankopedia.use((state) => state.protagonist);
const protagonistEquipment = useEquipment(protagonistTank.tank!); const protagonistEquipment = useEquipment(protagonistTank.tank!);
@@ -41,14 +38,13 @@ export const Page = withErrorWrapper(
return ( return (
<div className={styles.page}> <div className={styles.page}>
<div className={styles.loadout}>
<TankopediaLoadout characteristics={characteristics} />
</div>
<div className={styles.sandbox}> <div className={styles.sandbox}>
<TankopediaSandbox /> <TankopediaSandbox />
<TankopediaCharacteristics /> <TankopediaCharacteristics />
<TankopediaNavigation />
</div>
<div className={styles.stats}>
<TankopediaLoadout characteristics={characteristics} />
</div> </div>
</div> </div>
); );
@@ -6,7 +6,6 @@ import { characteristicsOrder } from "../tankopedia/characteristicsOrder";
interface Tankopedia { interface Tankopedia {
compare: TankopediaCompare; compare: TankopediaCompare;
tab: TankopediaTab;
groups: Record<string, boolean>; groups: Record<string, boolean>;
protagonist: TankState; protagonist: TankState;
@@ -18,11 +17,6 @@ export enum TankopediaCompare {
All, All,
} }
export enum TankopediaTab {
Tank,
Characteristics,
}
const groups: Record<string, boolean> = {}; const groups: Record<string, boolean> = {};
for (const { group } of characteristicsOrder) { for (const { group } of characteristicsOrder) {
@@ -31,7 +25,6 @@ for (const { group } of characteristicsOrder) {
export const Tankopedia = new Varuna<Tankopedia, Tank>((tank) => ({ export const Tankopedia = new Varuna<Tankopedia, Tank>((tank) => ({
compare: TankopediaCompare.TierAndClass, compare: TankopediaCompare.TierAndClass,
tab: TankopediaTab.Characteristics,
groups, groups,
protagonist: createTankState(tank), protagonist: createTankState(tank),