https and ssl integration on the backend, frontend and started integration of logistics app as a separate frontend

This commit is contained in:
GotthardG
2024-11-19 09:56:05 +01:00
parent a91d74b718
commit a931bfb8ec
14 changed files with 264 additions and 267 deletions

View File

@ -1,75 +1,64 @@
import React from 'react';
import { Box } from '@mui/material';
import { QrCode, AcUnit, AccessTime } from '@mui/icons-material';
import { Box, Typography } from '@mui/material';
import styled from 'styled-components';
interface SlotProps {
data: SlotData;
onSelect: (slot: SlotData) => void;
isSelected: boolean;
}
import LocalGasStationIcon from '@mui/icons-material/LocalGasStation'; // Icon for refilling indicator.
export interface SlotData {
id: string;
qr_code: string;
label: string;
qr_base: string;
occupied: boolean;
needsRefill: boolean;
timeUntilRefill: string;
dewar_unique_id?: string; // Optional additional information.
dewar_name?: string; // Optional dewar information.
needs_refill?: boolean; // Indicator for refill requirement.
}
const SlotContainer = styled(Box)<{ isOccupied: boolean, isSelected: boolean }>`
width: 90px;
height: 180px;
margin: 10px;
background-color: ${({ isOccupied }) => (isOccupied ? '#ffebee' : '#e8f5e9')}; /* occupied = light red, free = light green */
border: ${({ isSelected }) => (isSelected ? '3px solid blue' : '2px solid #aaaaaa')};
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
interface SlotProps {
data: SlotData;
isSelected: boolean;
onSelect: (slot: SlotData) => void;
}
const StyledSlot = styled(Box)<{ isSelected: boolean; isOccupied: boolean }>`
padding: 16px;
margin: 8px;
width: 150px; // Increase the width to accommodate more info.
height: 150px; // Increase the height to accommodate more info.
background-color: ${({ isSelected, isOccupied }) =>
isSelected ? '#3f51b5' : isOccupied ? '#f44336' : '#4caf50'};
color: white;
cursor: pointer;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
padding: 10px;
box-sizing: border-box;
cursor: pointer;
position: relative;
border-radius: 8px;
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
transition: transform 0.2s;
&:hover {
transform: scale(1.05);
}
`;
const SlotNumber = styled.div`
font-size: 20px;
font-weight: bold;
`;
const QrCodeIcon = styled(QrCode)`
font-size: 40px;
color: #aaaaaa;
`;
const RefillIcon = styled(AcUnit)`
font-size: 20px;
color: #1e88e5;
margin-top: auto;
`;
const ClockIcon = styled(AccessTime)`
font-size: 20px;
color: #ff6f00;
`;
const Slot: React.FC<SlotProps> = ({ data, onSelect, isSelected }) => {
const { id, occupied, needsRefill, timeUntilRefill } = data;
const Slot: React.FC<SlotProps> = ({ data, isSelected, onSelect }) => {
return (
<SlotContainer isOccupied={occupied} onClick={() => onSelect(data)} isSelected={isSelected}>
<SlotNumber>{id}</SlotNumber>
<QrCodeIcon />
{occupied && (
<>
{needsRefill && <RefillIcon titleAccess="Needs Refill" />}
<ClockIcon titleAccess={`Time until refill: ${timeUntilRefill}`} />
</>
<StyledSlot
isSelected={isSelected}
isOccupied={data.occupied}
onClick={() => onSelect(data)}
>
<Typography variant="h6">{data.label}</Typography>
{data.dewar_name && (
<Typography variant="body2">{`Dewar: ${data.dewar_name}`}</Typography>
)}
</SlotContainer>
{data.dewar_unique_id && (
<Typography variant="body2">{`ID: ${data.dewar_unique_id}`}</Typography>
)}
{data.needs_refill && <LocalGasStationIcon />}
</StyledSlot>
);
}
};
export default Slot;

View File

@ -1,7 +1,7 @@
import React, { useState } from 'react';
import { Box, Typography } from '@mui/material';
import styled from 'styled-components';
import Slot, { SlotData } from './Slots';
import Slot, { SlotData } from '../components/Slots';
const StorageContainer = styled(Box)`
display: flex;
@ -26,91 +26,41 @@ const StorageWrapper = styled.div`
interface StorageProps {
name: string;
selectedSlot: string | null;
slotsData: SlotData[];
onSelectSlot: (slot: SlotData) => void;
}
const storageSlotsData: { [key: string]: SlotData[] } = {
"X06SA-storage": [
{ id: "A1-X06SA", occupied: false, needsRefill: false, timeUntilRefill: '' },
{ id: "A2-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "A3-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "A4-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "A5-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "B1-X06SA", occupied: false, needsRefill: false, timeUntilRefill: '' },
{ id: "B2-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "B3-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "B4-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "B5-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "C1-X06SA", occupied: false, needsRefill: false, timeUntilRefill: '' },
{ id: "C2-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "C3-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "C4-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "C5-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "D1-X06SA", occupied: false, needsRefill: false, timeUntilRefill: '' },
{ id: "D2-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "D3-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "D4-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "D5-X06SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
],
"X10SA-storage": [
{ id: "A1-X10SA", occupied: false, needsRefill: false, timeUntilRefill: '' },
{ id: "A2-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "A3-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "A4-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "A5-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "B1-X10SA", occupied: false, needsRefill: false, timeUntilRefill: '' },
{ id: "B2-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "B3-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "B4-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "B5-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "C1-X10SA", occupied: false, needsRefill: false, timeUntilRefill: '' },
{ id: "C2-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "C3-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "C4-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "C5-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "D1-X10SA", occupied: false, needsRefill: false, timeUntilRefill: '' },
{ id: "D2-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "D3-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "D4-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
{ id: "D5-X10SA", occupied: true, needsRefill: true, timeUntilRefill: '12h' },
],
"Novartis-Box": [
{ id: "NB1", occupied: true, needsRefill: true, timeUntilRefill: '6h' },
{ id: "NB2", occupied: true, needsRefill: true, timeUntilRefill: '6h' },
{ id: "NB3", occupied: true, needsRefill: true, timeUntilRefill: '6h' },
{ id: "NB4", occupied: true, needsRefill: true, timeUntilRefill: '6h' },
{ id: "NB5", occupied: true, needsRefill: true, timeUntilRefill: '6h' },
{ id: "NB6", occupied: true, needsRefill: true, timeUntilRefill: '6h' },
],
};
const Storage: React.FC<StorageProps> = ({ name, selectedSlot }) => {
const Storage: React.FC<StorageProps> = ({ name, selectedSlot, slotsData, onSelectSlot }) => {
const [highlightedSlot, setHighlightedSlot] = useState<SlotData | null>(null);
const handleSlotSelect = (slot: SlotData) => {
setHighlightedSlot(slot);
onSelectSlot(slot);
console.log('Selected slot:', slot);
};
console.log("Rendering Storage Component with name:", name);
return (
<StorageContainer>
<Typography variant="h5">{name} Slots</Typography>
<StorageWrapper>
{storageSlotsData[name].map((slot) => (
{slotsData.map((slot: SlotData) => (
<Slot
key={slot.id}
data={slot}
onSelect={handleSlotSelect}
isSelected={selectedSlot === slot.id}
isSelected={selectedSlot === slot.qr_code}
/>
))}
</StorageWrapper>
{highlightedSlot && (
<Typography variant="subtitle1">
Selected Slot: {highlightedSlot.id}
Selected Slot: {highlightedSlot.label}
</Typography>
)}
</StorageContainer>
);
}
};
export default Storage;