Inventory mockup (experimental)
This commit is contained in:
3
app/components/agent.tsx
Normal file
3
app/components/agent.tsx
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function Agent({side}: {side: "T" | "CT"}) {
|
||||||
|
return <>{side}</>
|
||||||
|
}
|
||||||
132
app/components/inventory.tsx
Normal file
132
app/components/inventory.tsx
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { Skeleton, Surface } from "@heroui/react";
|
||||||
|
import { Agent } from "./agent";
|
||||||
|
import { Weapon } from "./weapon";
|
||||||
|
import { useNotification } from "~/hooks/notification";
|
||||||
|
|
||||||
|
export function Inventory({ side }: { side: "T" | "CT" }) {
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [agent, setAgent] = useState({});
|
||||||
|
const [gloves, setGloves] = useState({ name: "", color: "", paint_index: 0 });
|
||||||
|
const [knife, setKnife] = useState({ name: "", color: "", paint_index: 0 });
|
||||||
|
const [weapons, setWeapons] = useState([]);
|
||||||
|
const { notify } = useNotification();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetch_weapons = async () => {
|
||||||
|
let response = await fetch(
|
||||||
|
`${import.meta.env.VITE_BASE_API_URL}/knife?team=${side}`,
|
||||||
|
{ credentials: "include" },
|
||||||
|
)
|
||||||
|
.then((r) => r.json())
|
||||||
|
.catch((e) => {
|
||||||
|
notify(
|
||||||
|
{
|
||||||
|
type: "danger",
|
||||||
|
loading: false,
|
||||||
|
title: "An error occured.",
|
||||||
|
message: `An error occured: ${e}`,
|
||||||
|
},
|
||||||
|
10000,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
setKnife(response);
|
||||||
|
|
||||||
|
response = await fetch(
|
||||||
|
`${import.meta.env.VITE_BASE_API_URL}/gloves?team=${side}`,
|
||||||
|
{ credentials: "include" },
|
||||||
|
)
|
||||||
|
.then((r) => r.json())
|
||||||
|
.catch((e) => {
|
||||||
|
notify(
|
||||||
|
{
|
||||||
|
type: "danger",
|
||||||
|
loading: false,
|
||||||
|
title: "An error occured.",
|
||||||
|
message: `An error occured: ${e}`,
|
||||||
|
},
|
||||||
|
10000,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
setGloves(response)
|
||||||
|
setLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (loading) fetch_weapons();
|
||||||
|
}, [loading]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setLoading(true);
|
||||||
|
}, [side]);
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-1 gap-2 min-h-0">
|
||||||
|
<Surface
|
||||||
|
className="flex flex-col rounded-xl w-1/3 p-4 gap-2"
|
||||||
|
variant="secondary"
|
||||||
|
>
|
||||||
|
<Skeleton className="flex-1 h-40 w-full rounded-xl" />
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Skeleton className="flex-1 h-40 rounded-xl" />
|
||||||
|
<Skeleton className="flex-1 h-40 rounded-xl" />
|
||||||
|
<Skeleton className="flex-1 h-40 rounded-xl" />
|
||||||
|
</div>
|
||||||
|
</Surface>
|
||||||
|
<Surface
|
||||||
|
className="flex-1 flex flex-col rounded-xl w-2/3 p-4"
|
||||||
|
variant="secondary"
|
||||||
|
>
|
||||||
|
<div className="absolute inset-4 flex-1 grid grid-cols-5 gap-2 overflow-y-scroll">
|
||||||
|
{Array.from({ length: 50 }, (_, index) => (
|
||||||
|
<Skeleton key={index} className="flex-1 h-40 rounded-xl" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Surface>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-1 gap-2 min-h-0">
|
||||||
|
<Surface
|
||||||
|
className="flex flex-col rounded-xl w-1/3 p-4 gap-2"
|
||||||
|
variant="secondary"
|
||||||
|
>
|
||||||
|
<Agent side={side}></Agent>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Weapon
|
||||||
|
weapon_id={knife["name"]}
|
||||||
|
color={knife["color"]}
|
||||||
|
paint_index={knife["paint_index"]}
|
||||||
|
></Weapon>
|
||||||
|
<Weapon
|
||||||
|
weapon_id={gloves["name"]}
|
||||||
|
color={gloves["color"]}
|
||||||
|
paint_index={gloves["paint_index"]}
|
||||||
|
></Weapon>
|
||||||
|
<Weapon
|
||||||
|
weapon_id={"agent-4730"}
|
||||||
|
color="#8847ff"
|
||||||
|
></Weapon>
|
||||||
|
</div>
|
||||||
|
</Surface>
|
||||||
|
<Surface
|
||||||
|
className="flex-1 flex flex-col rounded-xl w-2/3 p-4"
|
||||||
|
variant="secondary"
|
||||||
|
>
|
||||||
|
<div className="absolute inset-4 flex-1 grid grid-cols-5 gap-2 overflow-y-scroll">
|
||||||
|
{Array.from({ length: 50 }, (_, index) => (
|
||||||
|
<Weapon
|
||||||
|
key={index}
|
||||||
|
weapon_id="weapon_ak47"
|
||||||
|
color="#e4ae39"
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Surface>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
24
app/components/weapon.tsx
Normal file
24
app/components/weapon.tsx
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { Button } from "@heroui/react";
|
||||||
|
|
||||||
|
export function Weapon({
|
||||||
|
weapon_id,
|
||||||
|
color,
|
||||||
|
paint_index = 0,
|
||||||
|
}: {
|
||||||
|
weapon_id: string;
|
||||||
|
color: string;
|
||||||
|
paint_index?: number;
|
||||||
|
}) {
|
||||||
|
const acolor = `${color}64`
|
||||||
|
return (
|
||||||
|
<Button className="flex flex-col h-fit w-fit p-0 rounded-none bg-transparent gap-0 hover:bg-indigo-800 active:bg-indigo-900">
|
||||||
|
<div className="bg-linear-to-b pointer-events-none" style={{background: `linear-gradient(to bottom, #1f2937, ${acolor})`}}>
|
||||||
|
<img
|
||||||
|
src={`/public/skins/${weapon_id}_${paint_index}.png`}
|
||||||
|
className="pointer-events-none"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className={`h-1 w-full`} style={{background: `${color}`}}></div>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,5 +1,48 @@
|
|||||||
|
import { useState } from "react";
|
||||||
import Base from "./base";
|
import Base from "./base";
|
||||||
|
import { Surface, Tabs } from "@heroui/react";
|
||||||
|
import { Inventory } from "~/components/inventory";
|
||||||
|
|
||||||
export function InventoryPage() {
|
export function InventoryPage() {
|
||||||
return <Base needsLogin>INVENTORY</Base>;
|
const [side, setSide] = useState<"T" | "CT">("T");
|
||||||
|
return (
|
||||||
|
<Base needsLogin>
|
||||||
|
<Surface
|
||||||
|
className="flex flex-col flex-1 min-h-0 h-0 shadow-lg shadow-indigo-900 ring-1 ring-indigo-800 p-2 m-2 rounded-3xl gap-2"
|
||||||
|
variant="default"
|
||||||
|
>
|
||||||
|
<div className="w-full h-min flex">
|
||||||
|
<Tabs
|
||||||
|
selectedKey={side}
|
||||||
|
onSelectionChange={(key) => {
|
||||||
|
switch (key) {
|
||||||
|
case "T": {
|
||||||
|
setSide("T");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "CT": {
|
||||||
|
setSide("CT");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Tabs.ListContainer>
|
||||||
|
<Tabs.List>
|
||||||
|
<Tabs.Tab className="w-fit" id="T">
|
||||||
|
Terrorist
|
||||||
|
<Tabs.Indicator />
|
||||||
|
</Tabs.Tab>
|
||||||
|
<Tabs.Tab className="w-fit" id="CT">
|
||||||
|
Counter-Terrorist
|
||||||
|
<Tabs.Indicator />
|
||||||
|
</Tabs.Tab>
|
||||||
|
</Tabs.List>
|
||||||
|
</Tabs.ListContainer>
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
<Inventory side={side} />
|
||||||
|
</Surface>
|
||||||
|
</Base>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user