added optional timestamp

This commit is contained in:
Carter 2026-03-13 13:20:51 -06:00
parent b96787698b
commit 1e2003a541
7 changed files with 240 additions and 17 deletions

View file

@ -0,0 +1,38 @@
import { Typography } from "@mui/material";
import moment from "moment";
import { useEffect, useState } from "react";
interface Props {
/** RFC3339 timestamp string */
timestamp: string;
}
/**
* Displays a timestamp as relative time (e.g. "a minute ago", "5 seconds ago").
* Uses a subtle, muted typography style.
* Refreshes every 60 seconds to keep the relative text current.
*/
export default function RelativeTimestamp({ timestamp }: Props) {
const [, setTick] = useState(0);
useEffect(() => {
const interval = setInterval(() => setTick((t) => t + 1), 60000);
return () => clearInterval(interval);
}, []);
const date = moment(timestamp);
if (!date.isValid()) return null;
return (
<Typography
variant="caption"
sx={{
opacity: 0.7,
fontSize: "0.7rem",
fontStyle: "italic",
}}
>
{date.fromNow()}
</Typography>
);
}

View file

@ -3,10 +3,13 @@ import { green } from "@mui/material/colors";
import { makeStyles } from "@mui/styles";
import { Device } from "models";
import PulseBox from "./PulseBox";
import RelativeTimestamp from "./RelativeTimestamp";
import { or } from "utils";
import { useEffect, useState } from "react";
interface Props {
device: Device
device: Device;
showTimestamp?: boolean;
}
const useStyles = makeStyles((theme: Theme) => {
@ -48,7 +51,7 @@ const useStyles = makeStyles((theme: Theme) => {
})
export default function StatusDust(props: Props) {
const { device } = props;
const { device, showTimestamp } = props;
const classes = useStyles()
const colors = or(device.status.sen5x?.overlays.map(overlay => overlay.color), []);
@ -165,6 +168,11 @@ export default function StatusDust(props: Props) {
</Typography>
</Grid2>
</Grid2>
{showTimestamp && device.status.sen5x?.timestamp && (
<Grid2>
<RelativeTimestamp timestamp={device.status.sen5x.timestamp} />
</Grid2>
)}
</Grid2>
</PulseBox>
</Tooltip>

View file

@ -3,13 +3,14 @@ import { blue, deepOrange, teal } from "@mui/material/colors";
import { makeStyles } from "@mui/styles";
import { Device } from "models";
import PulseBox from "./PulseBox";
import RelativeTimestamp from "./RelativeTimestamp";
import { or } from "utils";
import { useEffect, useState } from "react";
interface Props {
device: Device
// noDust?: boolean;
gasType: "co2" | "co" | "no2" | "o2" | "all"
device: Device;
gasType: "co2" | "co" | "no2" | "o2" | "all";
showTimestamp?: boolean;
}
const useStyles = makeStyles((theme: Theme) => {
@ -61,7 +62,7 @@ const useStyles = makeStyles((theme: Theme) => {
})
export default function StatusGas(props: Props) {
const { device, gasType } = props;
const { device, gasType, showTimestamp } = props;
const classes = useStyles()
// console.log(noDust)
let colors: string[] = []
@ -203,6 +204,11 @@ export default function StatusGas(props: Props) {
Volt: {device.status[gas]?.millivolts.toFixed(1)}mV
</Typography>
</Grid2>
{showTimestamp && device.status[gas]?.timestamp && (
<Grid2>
<RelativeTimestamp timestamp={device.status[gas].timestamp} />
</Grid2>
)}
</Grid2>
</Grid2>
</PulseBox>

View file

@ -3,11 +3,13 @@ import { blue, orange } from "@mui/material/colors";
import { makeStyles } from "@mui/styles";
import { Device } from "models";
import PulseBox from "./PulseBox";
import RelativeTimestamp from "./RelativeTimestamp";
import { or } from "utils";
import { useEffect, useState } from "react";
interface Props {
device: Device
device: Device;
showTimestamp?: boolean;
}
const useStyles = makeStyles((theme: Theme) => {
@ -25,7 +27,7 @@ const useStyles = makeStyles((theme: Theme) => {
})
export default function StatusPlenum(props: Props) {
const { device } = props;
const { device, showTimestamp } = props;
const classes = useStyles()
const colors = or(device.status.plenum?.overlays.map(overlay => overlay.color), []);
@ -117,6 +119,11 @@ export default function StatusPlenum(props: Props) {
{device.status.plenum?.humidity.toFixed(1)}%
</Typography>
</Grid2>
{showTimestamp && device.status.plenum?.timestamp && (
<Grid2>
<RelativeTimestamp timestamp={device.status.plenum.timestamp} />
</Grid2>
)}
</Grid2>
</PulseBox>
</Tooltip>

View file

@ -3,12 +3,14 @@ import { blue, green, orange } from "@mui/material/colors";
import { makeStyles } from "@mui/styles";
import { Device } from "models";
import PulseBox from "./PulseBox";
import RelativeTimestamp from "./RelativeTimestamp";
import { or } from "utils";
import { useEffect, useState } from "react";
interface Props {
device: Device
device: Device;
noDust?: boolean;
showTimestamp?: boolean;
}
const useStyles = makeStyles((theme: Theme) => {
@ -50,7 +52,7 @@ const useStyles = makeStyles((theme: Theme) => {
})
export default function StatusSen5x(props: Props) {
const { device, noDust } = props;
const { device, noDust, showTimestamp } = props;
const classes = useStyles()
// console.log(noDust)
const colors = or(device.status.sen5x?.overlays.map(overlay => overlay.color), []);
@ -200,6 +202,11 @@ export default function StatusSen5x(props: Props) {
</Typography>
</Grid2>
</Grid2>}
{showTimestamp && device.status.sen5x?.timestamp && (
<Grid2>
<RelativeTimestamp timestamp={device.status.sen5x.timestamp} />
</Grid2>
)}
</Grid2>
</PulseBox>
</Tooltip>