diff --git a/backend/app/models.py b/backend/app/models.py index 469448c..4107db3 100644 --- a/backend/app/models.py +++ b/backend/app/models.py @@ -156,6 +156,5 @@ class LogisticsEvent(Base): slot_id = Column(Integer, ForeignKey('slots.id')) # corrected table name event_type = Column(String, index=True) timestamp = Column(DateTime, default=datetime.utcnow) - action_details = Column(String) dewar = relationship("Dewar", back_populates="events") slot = relationship("Slot", back_populates="events") \ No newline at end of file diff --git a/backend/app/routers/logistics.py b/backend/app/routers/logistics.py index f38f5d2..c98e792 100644 --- a/backend/app/routers/logistics.py +++ b/backend/app/routers/logistics.py @@ -103,7 +103,6 @@ async def refill_dewar(qr_code: str, db: Session = Depends(get_db)): slot_id=None, event_type="refill", timestamp=now, - action_details=f"{dewar.unique_id} refilled" ) db.add(new_event) db.commit() diff --git a/logistics/src/components/Slots.tsx b/logistics/src/components/Slots.tsx index 1bc0aa7..96139bb 100644 --- a/logistics/src/components/Slots.tsx +++ b/logistics/src/components/Slots.tsx @@ -3,6 +3,7 @@ import { Box, Typography, Button, Alert } from '@mui/material'; import styled from 'styled-components'; import LocalGasStationIcon from '@mui/icons-material/LocalGasStation'; import CountdownTimer from './CountdownTimer'; +import QRCode from 'react-qr-code'; export interface SlotData { id: string; @@ -20,7 +21,7 @@ interface SlotProps { data: SlotData; isSelected: boolean; onSelect: (data: SlotData) => void; - onRefillDewar: (qr_code?: string) => Promise; + onRefillDewar: (dewar_unique_id?: string) => Promise; reloadSlots: () => Promise; } @@ -33,7 +34,7 @@ const StyledSlot = styled(Box)` padding: 16px; margin: 8px; width: 150px; - height: 220px; + height: 260px; background-color: ${({ isSelected, isOccupied }) => isSelected ? '#3f51b5' : isOccupied ? '#f44336' : '#4caf50'}; color: white; @@ -51,9 +52,48 @@ const StyledSlot = styled(Box)` } `; +const QRCodeContainer = styled.div` + padding: 8px; + background-color: white; + border-radius: 8px; +`; + +const BottleIcon: React.FC<{ fillHeight: number }> = ({ fillHeight }) => { + const pixelHeight = (276.777 * fillHeight) / 100; + const yPosition = 276.777 - pixelHeight; + + return ( + + + + + + + + + + ); +}; + const Slot: React.FC = ({ data, isSelected, onSelect, onRefillDewar, reloadSlots }) => { + const calculateFillHeight = (timeUntilRefill?: number) => { + if (timeUntilRefill === undefined || timeUntilRefill <= 0) { + return 0; + } + const maxTime = 86400; + return Math.min((timeUntilRefill / maxTime) * 100, 100); + }; + + const fillHeight = calculateFillHeight(data.time_until_refill); + useEffect(() => { - console.log(`Updated time_until_refill: ${data.time_until_refill}`); + if (data.time_until_refill !== undefined) { + console.log(`Updated time_until_refill: ${data.time_until_refill}`); + } }, [data.time_until_refill]); const handleRefill = async () => { @@ -74,11 +114,18 @@ const Slot: React.FC = ({ data, isSelected, onSelect, onRefillDewar, > {label} {dewar_name && {`Dewar: ${dewar_name}`}} - {dewar_unique_id && {`ID: ${dewar_unique_id}`}} - {needs_refill && } - {dewar_unique_id && time_until_refill !== undefined && time_until_refill !== -1 && ( - + {dewar_unique_id && ( + + + )} + {needs_refill && } + {dewar_unique_id && ( + + )} + {(dewar_unique_id && time_until_refill !== undefined && time_until_refill !== -1) ? ( + + ) : null} {needs_refill && (