frontend/src/harvestPlan/HarvestPlanDisplay.tsx

209 lines
7.6 KiB
TypeScript

import {
Box,
Grid2 as Grid,
Theme,
Typography,
IconButton,
LinearProgress,
Drawer
} from "@mui/material";
import { Notes } from "@mui/icons-material";
import GrainDescriber from "grain/GrainDescriber";
import { Field, HarvestPlan } from "models";
import React, { useEffect, useState } from "react";
import { getThemeType } from "theme";
import Chat from "chat/Chat";
import { pond } from "protobuf-ts/pond";
import { useMobile } from "hooks";
import HarvestPlanActions from "./HarvestPlanActions";
import { makeStyles } from "@mui/styles";
interface Props {
plan: HarvestPlan;
permissions: pond.Permission[];
planField: Field;
loading: boolean;
fieldList?: Field[];
changePlan: (updatedPlan?: HarvestPlan) => void;
}
const useStyles = makeStyles((theme: Theme) => ({
dark: {
backgroundColor: getThemeType() === "light" ? "rgb(245, 245, 245)" : "rgb(50, 50, 50)",
padding: 5
},
light: {
backgroundColor: getThemeType() === "light" ? "rgb(235, 235, 235)" : "rgb(60, 60, 60)",
padding: 5
},
avatar: {
color: getThemeType() === "light" ? theme.palette.common.black : theme.palette.common.white,
backgroundColor: "transparent",
width: theme.spacing(5),
height: theme.spacing(5),
border: "1px solid",
borderColor: theme.palette.divider
}
}));
export default function HarvestPlanDisplay(props: Props) {
const { plan, loading, planField, fieldList, changePlan, permissions } = props;
const classes = useStyles();
const [openNote, setOpenNote] = useState(false);
const isMobile = useMobile();
const planTable = () => {
return (
<React.Fragment>
<Grid container direction="column">
<Grid className={classes.dark}>
<Box style={{ display: "flex", justifyContent: "space-between" }}>
<Typography variant="subtitle1">Break Even Yield (acre):</Typography>
<Typography variant="subtitle1">
{plan.bushelPrice() !== 0 ? (
(plan.totalEquipmentCost() + plan.totalMaterialCost()) /
plan.bushelPrice()
).toFixed(2) : 0}{" "}
BU
</Typography>
</Box>
</Grid>
<Grid className={classes.light}>
<Box style={{ display: "flex", justifyContent: "space-between" }}>
<Typography variant="subtitle1">Break Even Sales Price (BU):</Typography>
<Typography variant="subtitle1">
$
{plan.yieldTarget() !== 0 ? (
(plan.totalEquipmentCost() + plan.totalMaterialCost()) /
plan.yieldTarget()
).toFixed(2) : 0}
</Typography>
</Box>
</Grid>
</Grid>
<Grid container direction="column" style={{ marginTop: 20 }}>
<Grid className={classes.dark}>
<Box style={{ display: "flex", justifyContent: "space-between" }}>
<Typography variant="subtitle1">Harvest Year:</Typography>
<Typography variant="subtitle1">{plan.harvestYear()}</Typography>
</Box>
</Grid>
<Grid className={classes.light}>
<Box style={{ display: "flex", justifyContent: "space-between" }}>
<Typography variant="subtitle1">Title:</Typography>
<Typography variant="subtitle1">{plan.settings.title}</Typography>
</Box>
</Grid>
<Grid className={classes.dark}>
<Box style={{ display: "flex", justifyContent: "space-between" }}>
<Typography variant="subtitle1">Grain:</Typography>
<Typography variant="subtitle1">{GrainDescriber(plan.cropType()).name}</Typography>
</Box>
</Grid>
<Grid className={classes.light}>
<Box style={{ display: "flex", justifyContent: "space-between" }}>
<Typography variant="subtitle1">Variant:</Typography>
<Typography variant="subtitle1">{plan.grainType()}</Typography>
</Box>
</Grid>
<Grid className={classes.dark}>
<Box style={{ display: "flex", justifyContent: "space-between" }}>
<Typography variant="subtitle1">Bushel Price:</Typography>
<Typography variant="subtitle1">${plan.bushelPrice()}</Typography>
</Box>
</Grid>
<Grid className={classes.light}>
<Box style={{ display: "flex", justifyContent: "space-between" }}>
<Typography variant="subtitle1">Yield Target:</Typography>
<Typography variant="subtitle1">{plan.yieldTarget()}</Typography>
</Box>
</Grid>
<Grid className={classes.dark}>
<Box style={{ display: "flex", justifyContent: "space-between" }}>
<Typography variant="subtitle1">Total Cost (acre):</Typography>
<Typography variant="subtitle1">
${(plan.totalEquipmentCost() + plan.totalMaterialCost()).toFixed(2)}
</Typography>
</Box>
</Grid>
<Grid className={classes.light}>
<Box style={{ display: "flex", justifyContent: "space-between" }}>
<Typography variant="subtitle1">Total Cost:</Typography>
<Typography variant="subtitle1">
$
{(
(plan.totalEquipmentCost() + plan.totalMaterialCost()) *
planField.acres()
).toFixed(2)}
</Typography>
</Box>
</Grid>
</Grid>
</React.Fragment>
);
};
const noteDrawer = () => {
return (
<Drawer
anchor={isMobile ? "bottom" : "right"}
open={openNote}
onClose={() => setOpenNote(false)}>
<Box height={isMobile ? "50vh" : "100vh"} padding={2}>
<Typography style={{ fontWeight: 650 }}>Notes</Typography>
<Chat type={pond.NoteType.NOTE_TYPE_HARVEST_PLAN} objectKey={plan.key()} />
</Box>
</Drawer>
);
};
return (
<React.Fragment>
{loading ? (
<Box paddingTop="20px">
<LinearProgress color="primary" />
</Box>
) : (
<React.Fragment>
<IconButton
disabled={plan.key() === ""}
className={classes.avatar}
onClick={() => setOpenNote(true)}>
<Notes />
</IconButton>
<Box style={{ display: "flex", justifyContent: "space-between" }}>
<Typography
variant="h5"
style={{ fontWeight: 700, marginTop: "auto", marginBottom: "auto" }}>
{plan.key() !== "" ? plan.settings.title : "None Found"}
</Typography>
{!isMobile && permissions.includes(pond.Permission.PERMISSION_WRITE) && (
<HarvestPlanActions
planField={planField}
fieldList={fieldList}
plan={plan}
permissions={permissions}
refreshCallback={updatedPlan => {
changePlan(updatedPlan);
}} //possibly need to re-load plan here
/>
)}
</Box>
{isMobile && permissions.includes(pond.Permission.PERMISSION_WRITE) && (
<HarvestPlanActions
planField={planField}
fieldList={fieldList}
plan={plan}
permissions={permissions}
refreshCallback={updatedPlan => {
changePlan(updatedPlan);
}} //possibly need to re-load plan here
/>
)}
{plan.key() !== "" && planTable()}
</React.Fragment>
)}
{noteDrawer()}
</React.Fragment>
);
}