frontend/src/bin/BinSelector.tsx

155 lines
5 KiB
TypeScript

import { Grid2 as Grid, TextField } from "@mui/material";
import { ImportBins, jsonBin } from "common/DataImports/BinCables/BinCableImporter";
import SearchSelect, { Option } from "common/SearchSelect";
import { useMobile } from "hooks";
import { pond } from "protobuf-ts/pond";
import React, { useEffect, useState } from "react";
import { useGlobalState } from "providers";
interface Props {
optionsChanged: (binOptions: jsonBin[]) => void;
vertical?: boolean;
}
export default function BinSelector(props: Props) {
const { optionsChanged, vertical } = props;
const [{user}] = useGlobalState();
const isMobile = useMobile();
const [manufacturerOptions, SetManufacturerOptions] = useState<Option[]>([]);
const [manufacturer, SetManufacturer] = useState<Option | null>(null);
const [binStyle, setBinStyle] = useState<Option | null>(null); //flat bottom or hopper
const [minDiameter, setMinDiameter] = useState(0);
const [maxDiameter, setMaxDiameter] = useState(0);
//set the initial manufacturer options
useEffect(() => {
let stringOps: string[] = [];
let options: Option[] = [];
ImportBins().forEach((bin: jsonBin) => {
if (!stringOps.includes(bin.Manufacturer)) {
stringOps.push(bin.Manufacturer);
options.push({
label: bin.Manufacturer,
value: bin.Manufacturer
});
}
});
SetManufacturerOptions(options);
}, []);
useEffect(() => {
//start out with all the bins
let ops: jsonBin[] = [];
ImportBins().forEach((bin: jsonBin) => {
let addBin = true;
if (manufacturer) {
if (manufacturer.value !== bin.Manufacturer) {
addBin = false;
}
}
if (binStyle) {
if (binStyle.value !== bin.Bottom) {
addBin = false;
}
}
if (minDiameter !== 0) {
if (minDiameter > bin.Diameter) {
addBin = false;
}
}
if (maxDiameter !== 0) {
if (maxDiameter < bin.Diameter) {
addBin = false;
}
}
if (addBin) {
ops.push(bin);
}
});
optionsChanged(ops);
}, [manufacturer, binStyle, minDiameter, maxDiameter]); // eslint-disable-line react-hooks/exhaustive-deps
const binSelection = () => {
return (
<Grid container direction="row" spacing={2} alignContent="center" alignItems="center">
<Grid size={{ xs: isMobile || vertical ? 12 : 3 }}>
{/* manufacturer */}
<SearchSelect
selected={manufacturer}
changeSelection={(option: Option | null) => {
SetManufacturer(option);
}}
options={manufacturerOptions}
label="Bin Manufacturer"
loading={false}
/>
</Grid>
<Grid size={{ xs: isMobile || vertical ? 12 : 3 }}>
{/* binStyle */}
<SearchSelect
selected={binStyle}
changeSelection={(option: Option | null) => {
setBinStyle(option);
}}
options={[
{ label: "Flat", value: "Flat Bottom" },
{ label: "Hopper", value: "Hopper Bottom" }
]}
label="BinStyle"
loading={false}
/>
</Grid>
{/* bin use: at the moment all bins are farm/personal use so this is not needed yet */}
{/* <Grid item xs={3}>
<SearchSelect
selected={binUse}
changeSelection={(option: Option | null) => {
setBinUse(option);
}}
options={[
{label: "Farm", value: "Farm"},
{label: "Commercial", value: "Commercial"}
]}
label="BinStyle"
loading={false}
/>
</Grid> */}
<Grid size={{ xs: isMobile || vertical ? 12 : 3 }}>
{/* minD */}
<TextField
variant="outlined"
type="number"
value={minDiameter}
onChange={e => {
if (!isNaN(+e.target.value)) {
setMinDiameter(+e.target.value);
}
}}
label={
"Minimum Diameter " +
(user.distanceUnit() === pond.DistanceUnit.DISTANCE_UNIT_FEET ? "(ft)" : "(m)")
}
/>
</Grid>
<Grid size={{ xs: isMobile || vertical ? 12 : 3 }}>
{/* maxD */}
<TextField
variant="outlined"
type="number"
value={maxDiameter}
onChange={e => {
if (!isNaN(+e.target.value)) {
setMaxDiameter(+e.target.value);
}
}}
label={
"Maximum Diameter " +
(user.distanceUnit() === pond.DistanceUnit.DISTANCE_UNIT_FEET ? "(ft)" : "(m)")
}
/>
</Grid>
</Grid>
);
};
return <React.Fragment>{binSelection()}</React.Fragment>;
}