Introduced classes for weapons and agents and restructured code
This commit is contained in:
@@ -1,25 +1,16 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Skeleton, Surface } from "@heroui/react";
|
import { Skeleton, Surface } from "@heroui/react";
|
||||||
import { Agent } from "./agent";
|
import { Agent } from "./agent";
|
||||||
import { Weapon } from "./weapon";
|
import { SkinTile } from "./skin_tile";
|
||||||
import { useNotification } from "~/hooks/notification";
|
import { useNotification } from "~/hooks/notification";
|
||||||
|
import { WeaponInfo, AgentInfo } from "~/types/skin";
|
||||||
interface SkinInfo {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
color: string;
|
|
||||||
display: string;
|
|
||||||
paint_index: number;
|
|
||||||
float: number;
|
|
||||||
pattern: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Inventory({ side }: { side: "T" | "CT" }) {
|
export function Inventory({ side }: { side: "T" | "CT" }) {
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [agent, setAgent] = useState<SkinInfo>();
|
const [agent, setAgent] = useState<AgentInfo>();
|
||||||
const [gloves, setGloves] = useState<SkinInfo>();
|
const [gloves, setGloves] = useState<WeaponInfo>();
|
||||||
const [knife, setKnife] = useState<SkinInfo>();
|
const [knife, setKnife] = useState<WeaponInfo>();
|
||||||
const [weapons, setWeapons] = useState<Array<SkinInfo>>([]);
|
const [weapons, setWeapons] = useState<Array<WeaponInfo>>([]);
|
||||||
const { notify } = useNotification();
|
const { notify } = useNotification();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -41,7 +32,7 @@ export function Inventory({ side }: { side: "T" | "CT" }) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
setKnife(response[0]);
|
setKnife(new WeaponInfo(response[0]));
|
||||||
|
|
||||||
response = await fetch(
|
response = await fetch(
|
||||||
`${import.meta.env.VITE_BASE_API_URL}/skin?team=${side}&category=Gloves`,
|
`${import.meta.env.VITE_BASE_API_URL}/skin?team=${side}&category=Gloves`,
|
||||||
@@ -60,7 +51,7 @@ export function Inventory({ side }: { side: "T" | "CT" }) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
setGloves(response[0]);
|
setGloves(new WeaponInfo(response[0]));
|
||||||
|
|
||||||
response = await fetch(
|
response = await fetch(
|
||||||
`${import.meta.env.VITE_BASE_API_URL}/skin?team=${side}`,
|
`${import.meta.env.VITE_BASE_API_URL}/skin?team=${side}`,
|
||||||
@@ -79,7 +70,7 @@ export function Inventory({ side }: { side: "T" | "CT" }) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
setWeapons(response);
|
setWeapons(response.map((item: any) => (new WeaponInfo(item))));
|
||||||
|
|
||||||
response = await fetch(
|
response = await fetch(
|
||||||
`${import.meta.env.VITE_BASE_API_URL}/agent?team=${side}`,
|
`${import.meta.env.VITE_BASE_API_URL}/agent?team=${side}`,
|
||||||
@@ -98,7 +89,7 @@ export function Inventory({ side }: { side: "T" | "CT" }) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
setAgent(response);
|
setAgent(new AgentInfo(response));
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
@@ -149,31 +140,19 @@ export function Inventory({ side }: { side: "T" | "CT" }) {
|
|||||||
{agent && <Agent agent_id={agent["name"]}></Agent>}
|
{agent && <Agent agent_id={agent["name"]}></Agent>}
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
{knife && (
|
{knife && (
|
||||||
<Weapon
|
<SkinTile
|
||||||
weapon_id={knife["name"]}
|
skin={knife}
|
||||||
color={knife["color"]}
|
></SkinTile>
|
||||||
paint_index={knife["paint_index"]}
|
|
||||||
display={knife["display"]}
|
|
||||||
float={knife["float"]}
|
|
||||||
pattern={knife["pattern"]}
|
|
||||||
></Weapon>
|
|
||||||
)}
|
)}
|
||||||
{gloves && (
|
{gloves && (
|
||||||
<Weapon
|
<SkinTile
|
||||||
weapon_id={gloves["name"]}
|
skin={gloves}
|
||||||
color={gloves["color"]}
|
></SkinTile>
|
||||||
paint_index={gloves["paint_index"]}
|
|
||||||
display={gloves["display"]}
|
|
||||||
float={gloves["float"]}
|
|
||||||
pattern={gloves["pattern"]}
|
|
||||||
></Weapon>
|
|
||||||
)}
|
)}
|
||||||
{agent && (
|
{agent && (
|
||||||
<Weapon
|
<SkinTile
|
||||||
weapon_id={agent["name"]}
|
skin={agent}
|
||||||
color={agent["color"]}
|
></SkinTile>
|
||||||
display={agent["display"]}
|
|
||||||
></Weapon>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Surface>
|
</Surface>
|
||||||
@@ -183,14 +162,9 @@ export function Inventory({ side }: { side: "T" | "CT" }) {
|
|||||||
>
|
>
|
||||||
<div className="absolute inset-4 flex-1 grid grid-cols-5 gap-2 overflow-y-scroll">
|
<div className="absolute inset-4 flex-1 grid grid-cols-5 gap-2 overflow-y-scroll">
|
||||||
{weapons.map((v, i) => (
|
{weapons.map((v, i) => (
|
||||||
<Weapon
|
<SkinTile
|
||||||
key={i}
|
key={i}
|
||||||
weapon_id={v.name}
|
skin={v}
|
||||||
color={v.color}
|
|
||||||
paint_index={v.paint_index}
|
|
||||||
display={v.display}
|
|
||||||
float={v.float}
|
|
||||||
pattern={v.pattern}
|
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
58
app/components/skin_tile.tsx
Normal file
58
app/components/skin_tile.tsx
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import { Button, Typography } from "@heroui/react";
|
||||||
|
import { Float } from "./float";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { SkinDialog } from "./skin_dialog";
|
||||||
|
import { WeaponInfo, AgentInfo } from "~/types/skin";
|
||||||
|
|
||||||
|
export function SkinTile({ skin }: { skin: WeaponInfo | AgentInfo }) {
|
||||||
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||||
|
const acolor = `${skin.color}64`;
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<SkinDialog
|
||||||
|
isOpen={isDialogOpen}
|
||||||
|
setIsOpen={setIsDialogOpen}
|
||||||
|
skin={skin}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
onClick={() => setIsDialogOpen(true)}
|
||||||
|
className="bg-mist-700 flex flex-col h-full p-0 rounded-none gap-0 hover:bg-indigo-800 active:bg-indigo-900"
|
||||||
|
>
|
||||||
|
<div className="flex flex-col w-full h-full">
|
||||||
|
<div
|
||||||
|
className="bg-linear-to-b pointer-events-none w-full h-full"
|
||||||
|
style={{
|
||||||
|
background: `linear-gradient(to bottom, #1f2937, ${acolor})`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={`/skins/${skin.name}_${skin instanceof WeaponInfo ? skin.paint_index : 0}.png`}
|
||||||
|
className="pointer-events-none object-contain object-bottom h-full"
|
||||||
|
alt="Weapon image"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={`h-1 w-full`}
|
||||||
|
style={{ background: `${skin.color}` }}
|
||||||
|
></div>
|
||||||
|
<div className="px-2">
|
||||||
|
<Typography.Heading
|
||||||
|
level={6}
|
||||||
|
className="py-1 text-wrap"
|
||||||
|
>
|
||||||
|
{skin.display}
|
||||||
|
</Typography.Heading>
|
||||||
|
{skin instanceof WeaponInfo && (
|
||||||
|
<Float float={skin.float} />
|
||||||
|
)}
|
||||||
|
{skin instanceof WeaponInfo && (
|
||||||
|
<Typography.Paragraph>
|
||||||
|
Pattern: {skin.pattern}
|
||||||
|
</Typography.Paragraph>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
import { Button, Surface, Typography } from "@heroui/react";
|
|
||||||
import { Float } from "./float";
|
|
||||||
|
|
||||||
export function Weapon({
|
|
||||||
weapon_id,
|
|
||||||
color,
|
|
||||||
display = "Weapon",
|
|
||||||
float,
|
|
||||||
pattern,
|
|
||||||
paint_index = 0,
|
|
||||||
}: {
|
|
||||||
weapon_id: string;
|
|
||||||
color: string;
|
|
||||||
display?: string;
|
|
||||||
float?: number;
|
|
||||||
pattern?: number;
|
|
||||||
paint_index?: number;
|
|
||||||
}) {
|
|
||||||
const acolor = `${color}64`;
|
|
||||||
return (
|
|
||||||
<Button className="bg-mist-700 flex flex-col h-full p-0 rounded-none gap-0 hover:bg-indigo-800 active:bg-indigo-900">
|
|
||||||
<div className="flex flex-col w-full h-full">
|
|
||||||
<div
|
|
||||||
className="bg-linear-to-b pointer-events-none w-full h-full"
|
|
||||||
style={{
|
|
||||||
background: `linear-gradient(to bottom, #1f2937, ${acolor})`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src={`/skins/${weapon_id}_${paint_index || 0}.png`}
|
|
||||||
className="pointer-events-none object-contain object-bottom h-full"
|
|
||||||
alt="Weapon image"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={`h-1 w-full`}
|
|
||||||
style={{ background: `${color}` }}
|
|
||||||
></div>
|
|
||||||
<Typography.Heading level={6} className="px-2 py-1 text-wrap">
|
|
||||||
{display}
|
|
||||||
</Typography.Heading>
|
|
||||||
{float !== undefined && <Float float={float} />}
|
|
||||||
{pattern !== undefined && (
|
|
||||||
<Typography.Paragraph className="px-2">
|
|
||||||
Pattern: {pattern}
|
|
||||||
</Typography.Paragraph>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
24
app/types/skin.ts
Normal file
24
app/types/skin.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
export class WeaponInfo {
|
||||||
|
id!: string;
|
||||||
|
name!: string;
|
||||||
|
color!: string;
|
||||||
|
display!: string;
|
||||||
|
paint_index!: number;
|
||||||
|
float!: number;
|
||||||
|
pattern!: number;
|
||||||
|
|
||||||
|
constructor(data: WeaponInfo) {
|
||||||
|
Object.assign(this, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AgentInfo {
|
||||||
|
id!: string;
|
||||||
|
name!: string;
|
||||||
|
color!: string;
|
||||||
|
display!: string;
|
||||||
|
|
||||||
|
constructor(data: AgentInfo) {
|
||||||
|
Object.assign(this, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user