From ea13f97c5779c64424c8939944a1b5b9f73faf37 Mon Sep 17 00:00:00 2001 From: csawatzky Date: Thu, 11 Jun 2026 16:48:00 -0600 Subject: [PATCH] more visual tweaks and design, fixed a coule bugs and removed some console logs --- src/bin/3dView/Scene/Bin3dView.tsx | 4 +- src/bin/BinPlayer.tsx | 23 ++-- src/bin/BinTableExpanded.tsx | 136 +++++++++------------- src/bin/bin3dVisualizer.tsx | 47 +++++--- src/bin/binSensorsDisplay.tsx | 38 +++--- src/bin/binSummary/BinSummary.tsx | 178 ++++++++++------------------- src/bin/binTableView.tsx | 120 ++++++++++++------- src/theme/theme.ts | 4 +- 8 files changed, 257 insertions(+), 293 deletions(-) diff --git a/src/bin/3dView/Scene/Bin3dView.tsx b/src/bin/3dView/Scene/Bin3dView.tsx index f8107f4..36d6f27 100644 --- a/src/bin/3dView/Scene/Bin3dView.tsx +++ b/src/bin/3dView/Scene/Bin3dView.tsx @@ -138,8 +138,8 @@ export default function Bin3dView(props: Props) { { isPlaying.current = false; }; const originalBin = useRef(null); @@ -350,8 +351,6 @@ export default function BinPlayer(props: Props) { * then builds `statusCheckpoints` for playback over [startDate, endDate]. */ const startPlayer = async () => { - console.log(startDate.toISOString()) - console.log(endDate.toISOString()) originalBin.current = cloneDeep(bin); // capture before async work begins isPlaying.current = true; setIsPlayingState(true) @@ -369,8 +368,6 @@ const startPlayer = async () => { endDate, checkpointCountFromRange(startDate, endDate) ); - console.log(responses) - console.log(checkpoints) for (let i = 0; i < checkpoints.length; i++) { if (!isPlaying.current) { @@ -387,7 +384,6 @@ const startPlayer = async () => { setBin(newBin); setCurrentCheckpointTime(checkpoints[i].time) await new Promise(res => setTimeout(res, PLAYBACK_INTERVAL)); - console.log("next step") } isPlaying.current = false; setIsPlayingState(false) @@ -455,8 +451,10 @@ const dateSelector = () => { { return ( - + Heatmap @@ -111,8 +113,11 @@ export default function bin3dVisualizer(props: Props){ value={binDisplay} sx={{ borderRadius: 1, - bgcolor: 'rgba(255,255,255,0.08)', - '& .MuiSelect-select': { py: 1.5 }, + bgcolor: '#151E27', + '& .MuiSelect-select': { + py: isMobile ? 0.5 : 1.5, + fontSize: 13 + }, '& .MuiOutlinedInput-notchedOutline': { border: 'none' }, '&:hover .MuiOutlinedInput-notchedOutline': { border: 'none' }, '&.Mui-focused .MuiOutlinedInput-notchedOutline': { border: 'none' }, @@ -173,9 +178,12 @@ export default function bin3dVisualizer(props: Props){ } const controllerDisplay = () => { + if (fans && fans.length > 1 || heaters && heaters.length > 1){ + + return ( - - + + Controllers {fans && fans.map(fan => { @@ -187,15 +195,16 @@ export default function bin3dVisualizer(props: Props){ display: 'flex', justifyContent: 'space-between', alignItems: 'center', - bgcolor: 'rgba(255,255,255,0.05)', + // bgcolor: 'rgba(255,255,255,0.05)', + bgcolor: '#151E27', borderRadius: 1, px: 2, py: 1, }} > - {fan.name()} + {fan.name()} - + {isOn ? "ON" : "OFF"} - {heater.name()} + {heater.name()} - + {isOn ? "ON" : "OFF"} { return ( - + {binModeControl()} {heatmapDisplay()} @@ -397,7 +410,7 @@ export default function bin3dVisualizer(props: Props){ showMoisture={showMoisture && showLabels} // showGrain={showFill} // showHotspots={showHotspots} - xOffset={isMobile ? undefined : -150} + xOffset={isMobile ? undefined : -120} /> {isMobile ? mobileHUD() : desktopHUD()} diff --git a/src/bin/binSensorsDisplay.tsx b/src/bin/binSensorsDisplay.tsx index a2085e1..9785b5e 100644 --- a/src/bin/binSensorsDisplay.tsx +++ b/src/bin/binSensorsDisplay.tsx @@ -734,7 +734,7 @@ export default function BinSensorsDisplay(props: Props){ if(showGraphs && device){ let icon = GetComponentIcon(plenum.type(), plenum.subType(), themeType) return( - + + {tempHumidCard(plenum)} ) @@ -765,7 +765,7 @@ export default function BinSensorsDisplay(props: Props){ if(showGraphs && device){ let icon = GetComponentIcon(pressure.type(), pressure.subType(), themeType) return( - + + {pressureCard(pressure)} ) @@ -795,7 +795,7 @@ export default function BinSensorsDisplay(props: Props){ if(showGraphs && device){ let icon = GetComponentIcon(ambient.type(), ambient.subType(), themeType) return( - + + {tempHumidCard(ambient)} ) @@ -826,7 +826,7 @@ export default function BinSensorsDisplay(props: Props){ if(showGraphs && device){ let icon = GetComponentIcon(h.type(), h.subType(), themeType) return( - + + {tempHumidCard(h)} ) @@ -857,7 +857,7 @@ export default function BinSensorsDisplay(props: Props){ if(showGraphs && device){ let icon = GetComponentIcon(co2.type(), co2.subType(), themeType) return( - + + {co2Card(co2)} ) @@ -887,7 +887,7 @@ export default function BinSensorsDisplay(props: Props){ if(showGraphs && device){ let icon = GetComponentIcon(lidar.type(), lidar.subType(), themeType) return( - + + {lidarCard(lidar)} ) @@ -917,7 +917,7 @@ export default function BinSensorsDisplay(props: Props){ if(showGraphs && device){ let icon = GetComponentIcon(cable.type(), cable.subType(), themeType) return( - + + {cableCard(cable)} ) @@ -957,7 +957,7 @@ export default function BinSensorsDisplay(props: Props){ if(showGraphs && device){ let icon = GetComponentIcon(heater.type(), heater.subType(), themeType) return( - + + {controllerCard(heater)} ) @@ -987,7 +987,7 @@ export default function BinSensorsDisplay(props: Props){ if(showGraphs && device){ let icon = GetComponentIcon(fan.type(), fan.subType(), themeType) return( - + + {controllerCard(fan)} ) @@ -1020,7 +1020,7 @@ export default function BinSensorsDisplay(props: Props){ Unassigned Components {unassignedComponents.map(comp => ( - + {unassignedComponentCard(comp)} ))} diff --git a/src/bin/binSummary/BinSummary.tsx b/src/bin/binSummary/BinSummary.tsx index f868712..6d39c25 100644 --- a/src/bin/binSummary/BinSummary.tsx +++ b/src/bin/binSummary/BinSummary.tsx @@ -113,125 +113,69 @@ export default function BinSummary(props: Props){ return bin.grainInventory(user) } - const inventorySummaryMobile = () => { - return ( - - - - {/* Grain Type */} + const inventorySummaryMobile = () => ( + + {/* Header row */} + + + setOpenGrainDialog(true)}> + + - - Grain Type - - setOpenGrainDialog(true)} - sx={{ - cursor: "pointer", - mt: 0.5, - px: 1, - py: 0.5, - borderRadius: 1, - border: "1px solid", - borderColor: grey[700], - "&:hover": { - borderColor: grey[500], - backgroundColor: "rgba(255,255,255,0.05)", - }, - }} - > - - {bin.grainName()} - + Grain type + {bin.grainName()} - - {/* Bin Fill */} - - - Bin Fill - - - {/* Top line: current / capacity */} - - {currentFill()} / {bin.grainCapacity(user)} - - {/* Bottom line: bar/slider + percent */} - - {bin.inventoryControl() === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_MANUAL ? ( - setOpenNewTransaction(true)} - onChange={(_, val) => { - let fillPercent = val as number - setManualFillPercent(fillPercent) - setManualBushels((fillPercent / 100) * bin.bushelCapacity()) - }} - min={0} - max={100} - sx={{ - flexGrow: 1, - color: "#4caf50", - "& .MuiSlider-thumb": { width: 16, height: 16 }, - "& .MuiSlider-rail": { backgroundColor: "rgba(255,255,255,0.1)" }, - }} - /> - ) : ( - - )} - - {bin.inventoryControl() === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_MANUAL - ? manualFillPercent - : bin.fillPercent()}% - - - - - - {/* Last Updated */} - - - Last Updated - - - - {/* Top line: time */} - - - - {moment(bin.status.timestamp).fromNow()} - - - {/* Bottom line: live/inactive status */} - - {activity(bin.status.timestamp)} - - - - - - - ); - } + + + + Last updated + {moment(bin.status.timestamp).fromNow()} + + + + + {/* Fill row */} + + + Bin fill + + + {bin.inventoryControl() === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_MANUAL + ? manualFillPercent : bin.fillPercent()}% + + + {currentFill().toLocaleString()} / {bin.grainCapacity(user).toLocaleString()} + + + + {bin.inventoryControl() === pond.BinInventoryControl.BIN_INVENTORY_CONTROL_MANUAL ? ( + + setOpenNewTransaction(true)} + onChange={(_, val) => { setManualFillPercent(val as number); setManualBushels((val as number / 100) * bin.bushelCapacity()); }} + min={0} max={100} sx={{ + color: "#4caf50", + py: 0, + mt: 0, + mb: 0, + height: 4, + "& .MuiSlider-root": { py: 0 }, + "& .MuiSlider-thumb": { width: 16, height: 16 }, + "& .MuiSlider-rail": { backgroundColor: "rgba(255,255,255,0.1)" }, + }} /> + + ) : ( + + )} + + + ); const inventorySummaryDesktop = () => { return ( - + {/* Grain Type */} @@ -395,7 +339,7 @@ export default function BinSummary(props: Props){ {loading ? : - + {setBin && - + } @@ -420,7 +364,7 @@ export default function BinSummary(props: Props){ {loading ? : - + : - + } diff --git a/src/bin/binTableView.tsx b/src/bin/binTableView.tsx index 33fcf6a..0659335 100644 --- a/src/bin/binTableView.tsx +++ b/src/bin/binTableView.tsx @@ -1,5 +1,5 @@ import { Edit, GppGood, Info, Save } from "@mui/icons-material"; -import { Box, Button, darken, DialogActions, IconButton, Table, TableBody, TableCell, TableHead, TableRow, TextField, Theme, Tooltip, Typography } from "@mui/material"; +import { Box, Button, darken, DialogActions, IconButton, Table, TableBody, TableCell, TableHead, TableRow, TextField, Theme, Tooltip, Typography, useTheme } from "@mui/material"; import { green, grey, orange, red, yellow } from "@mui/material/colors"; import { makeStyles } from "@mui/styles"; import ResponsiveDialog from "common/ResponsiveDialog"; @@ -22,34 +22,40 @@ const useStyles = makeStyles((theme: Theme) => ({ }, headerCellStyle: { fontWeight: 650, - backgroundColor: darken(theme.palette.background.paper, 0.2), + backgroundColor: darken(theme.palette.background.paper, 0.3), textAlign: "center", - borderTop: "1px solid black", - borderLeft: "1px solid black", - borderBottom: "1px solid black", - "&:last-child": { - borderRight: "1px solid black", - } + padding: 10 }, mobileHeaderCellStyle: { fontWeight: 650, - backgroundColor: darken(theme.palette.background.paper, 0.2), + backgroundColor: darken(theme.palette.background.paper, 0.3), textAlign: "center", - borderTop: "1px solid black", - borderLeft: "1px solid black", - borderBottom: "1px solid black", - "&:last-child": { - borderRight: "1px solid black", - }, padding: 2 }, - cellStyle: { - padding: 2, - fontWeight: 650, - fontSize: 17, + targetCellStyle: { textAlign: "center", - border: "1px solid black", - + backgroundColor: theme.palette.background.paper + }, + mobileTargetCellStyle: { + textAlign: "center", + backgroundColor: theme.palette.background.paper, + padding: 2 + }, + defaultCellStyle: { + padding: 2, + fontSize: 15, + textAlign: "center", + backgroundColor: darken(theme.palette.background.paper, 0.1), + borderTop: "1px solid " + darken(theme.palette.background.paper, 0.4), + borderBottom: "none" + }, + colouredCellStyle: { + padding: 2, + borderTop: "1px solid " + darken(theme.palette.background.paper, 0.4), + // fontWeight: 650, + fontSize: 15, + textAlign: "center", + borderBottom: "none" } }) ); @@ -71,6 +77,7 @@ export default function BinTableView(props: Props) { const classes = useStyles() const {bin, updateBinCallback} = props const [{user}] = useGlobalState() + const theme = useTheme() const [enterTemp, setEnterTemp] = useState(false) const [enterMoisture, setEnterMoisture] = useState(false) const [tempTarget, setTempTarget] = useState(0) @@ -163,13 +170,13 @@ export default function BinTableView(props: Props) { return levels },[bin]) - const levelDisplay = (level: BinLevel) => { + const levelDisplay = (level: BinLevel, lastRow?: boolean) => { let tempDisplay = "--" let moistureDisplay = "--" let lvlTemp let lvlMoisture - let tempColour: string = "" - let moistureColour: string = "" + let tempColour: string = darken(theme.palette.background.paper, 0.1) + let moistureColour: string = darken(theme.palette.background.paper, 0.1) //determine the temp if(level.grainTemps.length > 0){ @@ -207,12 +214,12 @@ export default function BinTableView(props: Props) { lvlMoisture = avg(level.airMoistures) } if(lvlMoisture){ - moistureDisplay = lvlMoisture.toFixed(2) + "%" + moistureDisplay = lvlMoisture.toFixed(2) } return ( - {tempDisplay} - {moistureDisplay} + {tempDisplay} + {moistureDisplay} ) } @@ -301,10 +308,11 @@ export default function BinTableView(props: Props) { {expandedTableDialog()} {/* Level Table */} - Grain Table + Grain Table