now with a working countdowntimer for each dewar

This commit is contained in:
GotthardG
2024-11-20 22:37:18 +01:00
parent cacf43b631
commit db610da588
7 changed files with 162 additions and 82 deletions

View File

@ -9,12 +9,14 @@ const CountdownTimer: React.FC<CountdownTimerProps> = ({ totalSeconds }) => {
const [timeLeft, setTimeLeft] = useState(totalSeconds);
useEffect(() => {
setTimeLeft(totalSeconds); // Reset timer on prop change
const timerId = setInterval(() => {
setTimeLeft(prev => Math.max(prev - 1, 0));
}, 1000);
return () => clearInterval(timerId);
}, []);
}, [totalSeconds]); // Listen to changes in totalSeconds
const formatTime = (seconds: number) => {
const hrs = Math.floor(seconds / 3600);
@ -23,8 +25,10 @@ const CountdownTimer: React.FC<CountdownTimerProps> = ({ totalSeconds }) => {
return `${hrs}h ${min}m ${sec}s`;
};
const timeColor = timeLeft < 300 ? 'red' : 'white'; // Red if less than 5 minutes remaining
return (
<Typography variant="body2" style={{ color: timeLeft < 300 ? 'red' : 'white' }} > {/* Warn with red color if less than 5 minutes */}
<Typography variant="body2" style={{ color: timeColor }}>
{`Time until refill: ${formatTime(timeLeft)}`}
</Typography>
);

View File

@ -1,8 +1,8 @@
import React from 'react';
import { Box, Typography } from '@mui/material';
import React, { useEffect } from 'react';
import { Box, Typography, Button, Alert } from '@mui/material';
import styled from 'styled-components';
import LocalGasStationIcon from '@mui/icons-material/LocalGasStation'; // Icon for refilling indicator.
import CountdownTimer from './CountdownTimer'; // Import the CountdownTimer component
import LocalGasStationIcon from '@mui/icons-material/LocalGasStation';
import CountdownTimer from './CountdownTimer';
export interface SlotData {
id: string;
@ -10,23 +10,30 @@ export interface SlotData {
label: string;
qr_base: string;
occupied: boolean;
dewar_unique_id?: string; // Optional additional information.
dewar_name?: string; // Optional dewar information.
needs_refill?: boolean; // Indicator for refill requirement.
time_until_refill?: number; // Time until refill in seconds, optional field
dewar_unique_id?: string;
dewar_name?: string;
needs_refill?: boolean;
time_until_refill?: number;
}
interface SlotProps {
data: SlotData;
isSelected: boolean;
onSelect: (slot: SlotData) => void;
onSelect: (data: SlotData) => void;
onRefillDewar: (qr_code?: string) => Promise<void>;
reloadSlots: () => Promise<void>;
}
const StyledSlot = styled(Box)<{ isSelected: boolean; isOccupied: boolean }>`
interface StyledSlotProps {
isSelected: boolean;
isOccupied: boolean;
}
const StyledSlot = styled(Box)<StyledSlotProps>`
padding: 16px;
margin: 8px;
width: 150px; // Increase the width to accommodate more info.
height: 200px; // Increase the height to accommodate more info.
width: 150px;
height: 220px;
background-color: ${({ isSelected, isOccupied }) =>
isSelected ? '#3f51b5' : isOccupied ? '#f44336' : '#4caf50'};
color: white;
@ -44,24 +51,41 @@ const StyledSlot = styled(Box)<{ isSelected: boolean; isOccupied: boolean }>`
}
`;
const Slot: React.FC<SlotProps> = ({ data, isSelected, onSelect }) => {
const Slot: React.FC<SlotProps> = ({ data, isSelected, onSelect, onRefillDewar, reloadSlots }) => {
useEffect(() => {
console.log(`Updated time_until_refill: ${data.time_until_refill}`);
}, [data.time_until_refill]);
const handleRefill = async () => {
if (data.dewar_unique_id) {
await onRefillDewar(data.dewar_unique_id);
reloadSlots();
}
};
const { id, qr_code, label, qr_base, occupied, needs_refill, time_until_refill, dewar_unique_id, dewar_name, ...rest } = data;
return (
<StyledSlot
isSelected={isSelected}
isOccupied={data.occupied}
isOccupied={occupied}
onClick={() => onSelect(data)}
{...rest}
>
<Typography variant="h6">{data.label}</Typography>
{data.dewar_name && (
<Typography variant="body2">{`Dewar: ${data.dewar_name}`}</Typography>
<Typography variant="h6">{label}</Typography>
{dewar_name && <Typography variant="body2">{`Dewar: ${dewar_name}`}</Typography>}
{dewar_unique_id && <Typography variant="body2">{`ID: ${dewar_unique_id}`}</Typography>}
{needs_refill && <LocalGasStationIcon />}
{dewar_unique_id && time_until_refill !== undefined && time_until_refill !== -1 && (
<CountdownTimer key={dewar_unique_id} totalSeconds={time_until_refill} />
)}
{data.dewar_unique_id && (
<Typography variant="body2">{`ID: ${data.dewar_unique_id}`}</Typography>
{needs_refill && (
<Button onClick={handleRefill} sx={{ mt: 1, color: 'white' }}>
Refill
</Button>
)}
{data.needs_refill && <LocalGasStationIcon />}
{/* Display countdown timer only for slots that have an associated dewar */}
{data.dewar_unique_id && data.time_until_refill !== undefined && (
<CountdownTimer totalSeconds={data.time_until_refill} />
{occupied && time_until_refill === -1 && (
<Alert severity="warning">This dewar has no recorded refill event. It needs to be refilled.</Alert>
)}
</StyledSlot>
);

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { Box, Typography } from '@mui/material';
import React from 'react';
import { Box, Typography, Button } from '@mui/material';
import styled from 'styled-components';
import Slot, { SlotData } from '../components/Slots';
@ -28,9 +28,10 @@ interface StorageProps {
selectedSlot: string | null;
slotsData: SlotData[];
onSelectSlot: (slot: SlotData) => void;
onRefillDewar: (slot: SlotData) => void; // Adjusted this prop to pass SlotData object
}
const Storage: React.FC<StorageProps> = ({ name, selectedSlot, slotsData, onSelectSlot }) => {
const Storage: React.FC<StorageProps> = ({ name, selectedSlot, slotsData, onSelectSlot, onRefillDewar }) => {
const handleSlotSelect = (slot: SlotData) => {
onSelectSlot(slot);
console.log('Selected slot:', slot);
@ -46,9 +47,23 @@ const Storage: React.FC<StorageProps> = ({ name, selectedSlot, slotsData, onSele
data={slot}
onSelect={handleSlotSelect}
isSelected={selectedSlot === slot.qr_code}
onRefillDewar={onRefillDewar} // Pass the refill handler to Slot component
/>
))}
</StorageWrapper>
<Button
variant="contained"
color="secondary"
onClick={() => {
const selectedSlotData = slotsData.find(slot => slot.qr_code === selectedSlot);
if (selectedSlotData) {
onRefillDewar(selectedSlotData);
} else {
alert('Please select a slot to refill its dewar.');
}
}}>
Refill Dewar
</Button>
</StorageContainer>
);
};