Files
CHOMPStation2/tgui/packages/tgui/interfaces/MiningVendor.js
2020-08-16 22:27:09 -07:00

180 lines
4.5 KiB
JavaScript

import { createSearch } from 'common/string';
import { Fragment } from 'inferno';
import { useBackend, useLocalState } from "../backend";
import { Box, Button, Collapsible, Dropdown, Flex, Input, NoticeBox, Section } from '../components';
import { Window } from "../layouts";
import { refocusLayout } from '../layouts';
import { MiningUser } from './common/Mining';
const sortTypes = {
'Alphabetical': (a, b) => a - b,
'By availability': (a, b) => -(a.affordable - b.affordable),
'By price': (a, b) => a.price - b.price,
};
export const MiningVendor = (props, context) => {
return (
<Window width={400} height={450} resizable>
<Window.Content className="Layout__content--flexColumn" scrollable>
<MiningUser insertIdText="Please insert an ID in order to make purchases." />
<MiningVendorSearch />
<MiningVendorItems />
</Window.Content>
</Window>
);
};
const MiningVendorItems = (props, context) => {
const { act, data } = useBackend(context);
const {
has_id,
id,
items,
} = data;
// Search thingies
const [
searchText,
_setSearchText,
] = useLocalState(context, 'search', '');
const [
sortOrder,
_setSortOrder,
] = useLocalState(context, 'sort', 'Alphabetical');
const [
descending,
_setDescending,
] = useLocalState(context, 'descending', false);
const searcher = createSearch(searchText, item => {
return item[0];
});
let has_contents = false;
let contents = Object.entries(items).map((kv, _i) => {
let items_in_cat = Object.entries(kv[1])
.filter(searcher)
.map(kv2 => {
kv2[1].affordable = has_id && id.points >= kv2[1].price;
return kv2[1];
})
.sort(sortTypes[sortOrder]);
if (items_in_cat.length === 0) {
return;
}
if (descending) {
items_in_cat = items_in_cat.reverse();
}
has_contents = true;
return (
<MiningVendorItemsCategory
key={kv[0]}
title={kv[0]}
items={items_in_cat}
/>
);
});
return (
<Flex.Item grow="1" overflow="auto">
<Section onClick={e => refocusLayout()}>
{has_contents
? contents : (
<Box color="label">
No items matching your criteria was found!
</Box>
)}
</Section>
</Flex.Item>
);
};
const MiningVendorSearch = (props, context) => {
const [
_searchText,
setSearchText,
] = useLocalState(context, 'search', '');
const [
_sortOrder,
setSortOrder,
] = useLocalState(context, 'sort', '');
const [
descending,
setDescending,
] = useLocalState(context, 'descending', false);
return (
<Box mb="0.5rem">
<Flex width="100%">
<Flex.Item grow="1" mr="0.5rem">
<Input
placeholder="Search by item name.."
width="100%"
onInput={(_e, value) => setSearchText(value)}
/>
</Flex.Item>
<Flex.Item basis="30%">
<Dropdown
selected="Alphabetical"
options={Object.keys(sortTypes)}
width="100%"
lineHeight="19px"
onSelected={v => setSortOrder(v)} />
</Flex.Item>
<Flex.Item>
<Button
icon={descending ? "arrow-down" : "arrow-up"}
height="19px"
tooltip={descending ? "Descending order" : "Ascending order"}
tooltipPosition="bottom-left"
ml="0.5rem"
onClick={() => setDescending(!descending)}
/>
</Flex.Item>
</Flex>
</Box>
);
};
const MiningVendorItemsCategory = (properties, context) => {
const { act, data } = useBackend(context);
const {
title,
items,
...rest
} = properties;
return (
<Collapsible open title={title} {...rest}>
{items.map(item => (
<Box key={item.name}>
<Box
display="inline-block"
verticalAlign="middle"
lineHeight="20px"
style={{
float: 'left',
}}>
{item.name}
</Box>
<Button
disabled={!data.has_id || data.id.points < item.price}
content={item.price.toLocaleString('en-US')}
width="15%"
textAlign="center"
style={{
float: 'right',
}}
onClick={() => act('purchase', {
cat: title,
name: item.name,
})}
/>
<Box
style={{
clear: "both",
}}
/>
</Box>
))}
</Collapsible>
);
};