initial-commit

This commit is contained in:
GotthardG
2024-10-24 10:31:09 +02:00
parent fbc9eb1873
commit b6611fdac0
55 changed files with 12587 additions and 0 deletions

View File

@ -0,0 +1,308 @@
import React from 'react';
import { Box, Typography, Button, Stack, TextField } from '@mui/material';
import ShipmentForm from './ShipmentForm.tsx';
import DewarDetails from './DewarDetails.tsx';
import { Shipment, Dewar, ContactPerson, Proposal, Address } from '../types.ts';
import { SxProps } from '@mui/system';
import QRCode from 'react-qr-code';
import bottleGrey from '../assets/icons/bottle-svgrepo-com-grey.svg';
import bottleYellow from '../assets/icons/bottle-svgrepo-com-yellow.svg';
import bottleGreen from '../assets/icons/bottle-svgrepo-com-green.svg';
import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
import AirplanemodeActiveIcon from "@mui/icons-material/AirplanemodeActive";
import StoreIcon from "@mui/icons-material/Store";
import DeleteIcon from "@mui/icons-material/Delete"; // Import delete icon
interface ShipmentDetailsProps {
selectedShipment: Shipment | null;
setSelectedDewar: React.Dispatch<React.SetStateAction<Dewar | null>>;
isCreatingShipment: boolean;
newShipment: Shipment;
setNewShipment: React.Dispatch<React.SetStateAction<Shipment>>;
handleSaveShipment: () => void;
contactPersons: ContactPerson[];
proposals: Proposal[];
returnAddresses: Address[];
sx?: SxProps;
}
const ShipmentDetails: React.FC<ShipmentDetailsProps> = ({
selectedShipment,
setSelectedDewar,
isCreatingShipment,
newShipment,
setNewShipment,
handleSaveShipment,
contactPersons,
proposals,
returnAddresses,
sx = {},
}) => {
const [localSelectedDewar, setLocalSelectedDewar] = React.useState<Dewar | null>(null);
const [trackingNumber, setTrackingNumber] = React.useState<string>('');
const [isAddingDewar, setIsAddingDewar] = React.useState<boolean>(false);
const [newDewar, setNewDewar] = React.useState<Partial<Dewar>>({
dewar_name: '',
tracking_number: '',
});
const shippingStatusMap: { [key: string]: string } = {
"not shipped": "grey",
"shipped": "yellow",
"arrived": "green",
};
const arrivalStatusMap: { [key: string]: string } = {
"not arrived": "grey",
"arrived": "green",
};
React.useEffect(() => {
if (localSelectedDewar) {
setTrackingNumber(localSelectedDewar.tracking_number);
}
}, [localSelectedDewar]);
if (!selectedShipment) {
return isCreatingShipment ? (
<ShipmentForm
newShipment={newShipment}
setNewShipment={setNewShipment}
handleSaveShipment={handleSaveShipment}
contactPersons={contactPersons}
proposals={proposals}
returnAddresses={returnAddresses}
/>
) : (
<Typography>No shipment selected.</Typography>
);
}
// Calculate total pucks and samples
const totalPucks = selectedShipment.dewars.reduce((acc, dewar) => acc + (dewar.number_of_pucks || 0), 0);
const totalSamples = selectedShipment.dewars.reduce((acc, dewar) => acc + (dewar.number_of_samples || 0), 0);
// Handle dewar selection
const handleDewarSelection = (dewar: Dewar) => {
setLocalSelectedDewar(prevDewar => (prevDewar?.tracking_number === dewar.tracking_number ? null : dewar));
setSelectedDewar(prevDewar => (prevDewar?.tracking_number === dewar.tracking_number ? null : dewar));
};
// Handle dewar deletion
const handleDeleteDewar = () => {
if (localSelectedDewar) {
const confirmed = window.confirm('Are you sure you want to delete this dewar?');
if (confirmed) {
const updatedDewars = selectedShipment.dewars.filter(dewar => dewar.tracking_number !== localSelectedDewar.tracking_number);
console.log('Updated Dewars:', updatedDewars); // Log or update state as needed
setLocalSelectedDewar(null); // Reset selection after deletion
}
}
};
// Handle form input changes for the new dewar
const handleNewDewarChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setNewDewar((prev) => ({
...prev,
[name]: value,
}));
};
// Handle adding a new dewar
const handleAddDewar = () => {
if (selectedShipment && newDewar.dewar_name) {
const updatedDewars = [
...selectedShipment.dewars,
{ ...newDewar, tracking_number: newDewar.tracking_number || `TN-${Date.now()}` } as Dewar,
];
setNewShipment({
...selectedShipment,
dewars: updatedDewars,
});
setIsAddingDewar(false);
setNewDewar({ dewar_name: '', number_of_pucks: 0, number_of_samples: 0, tracking_number: '' });
} else {
alert('Please fill in the Dewar Name');
}
};
// Function to generate QR Code (Placeholder)
const generateQRCode = () => {
console.log('Generate QR Code');
};
// Handle adding new contact person and return address
const addNewContactPerson = (name: string) => {
// Implementation to add a new contact person
console.log('Add new contact person:', name);
};
const addNewReturnAddress = (address: string) => {
// Implementation to add a new return address
console.log('Add new return address:', address);
};
return (
<Box sx={{ ...sx, padding: 2, textAlign: 'left' }}>
{/* Add Dewar Button - only visible if no dewar is selected */}
{!localSelectedDewar && !isAddingDewar && (
<Button
variant="contained"
onClick={() => setIsAddingDewar(true)}
sx={{ marginBottom: 2 }}
>
Add Dewar
</Button>
)}
{/* Add Dewar Form */}
{isAddingDewar && (
<Box sx={{ marginBottom: 2, width: '20%' }}>
<Typography variant="h6">Add New Dewar</Typography>
<TextField
label="Dewar Name"
name="dewar_name"
value={newDewar.dewar_name}
onChange={handleNewDewarChange}
fullWidth
sx={{ marginBottom: 2 }}
/>
<Button variant="contained" color="primary" onClick={handleAddDewar} sx={{ marginRight: 2 }}>
Save Dewar
</Button>
<Button variant="outlined" color="secondary" onClick={() => setIsAddingDewar(false)}>
Cancel
</Button>
</Box>
)}
<Typography variant="h5">{selectedShipment.shipment_name}</Typography>
<Typography variant="body1">Number of Pucks: {totalPucks}</Typography>
<Typography variant="body1">Number of Samples: {totalSamples}</Typography>
<Typography variant="body1">Shipment Date: {selectedShipment.shipment_date}</Typography>
<Stack spacing={1}>
{/* Render the DewarDetails component only if a dewar is selected */}
{localSelectedDewar && (
<DewarDetails
dewar={localSelectedDewar}
trackingNumber={trackingNumber}
setTrackingNumber={setTrackingNumber}
onGenerateQRCode={generateQRCode}
contactPersons={contactPersons} // Pass contact persons
returnAddresses={returnAddresses} // Pass return addresses
addNewContactPerson={addNewContactPerson} // Pass function to add a new contact person
addNewReturnAddress={addNewReturnAddress} // Pass function to add a new return address
shipping_date={localSelectedDewar?.shipping_date} // Ensure these are passed
arrival_date={localSelectedDewar?.arrival_date}
/>
)}
{selectedShipment.dewars.map((dewar: Dewar) => (
<Button
key={dewar.tracking_number}
onClick={() => handleDewarSelection(dewar)}
sx={{
width: '100%',
textAlign: 'left',
backgroundColor: localSelectedDewar?.tracking_number === dewar.tracking_number ? '#d0f0c0' : '#f0f0f0', // Highlight if selected
padding: 2,
display: 'flex',
alignItems: 'center',
}}
>
<Box
sx={{
width: 80,
height: 80,
backgroundColor: '#e0e0e0',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginRight: 2,
}}
>
{dewar.qrcode ? (
<QRCode value={dewar.qrcode} size={70} />
) : (
<Typography variant="body2" color="textSecondary">No QR code available</Typography>
)}
</Box>
<Box sx={{ flexGrow: 1, marginRight: 0 }}>
<Typography variant="body1">{dewar.dewar_name}</Typography>
<Typography variant="body2">Number of Pucks: {dewar.number_of_pucks || 0}</Typography>
<Typography variant="body2">Number of Samples: {dewar.number_of_samples || 0}</Typography>
<Typography variant="body2">Tracking Number: {dewar.tracking_number}</Typography>
</Box>
<Box sx={{ flexGrow: 1, display: 'flex', alignItems: 'center', flexDirection: 'row', justifyContent: 'space-evenly' }}>
{/* Status icons and date information */}
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
<img
src={dewar.status === "in preparation" ? bottleYellow : (dewar.status === "ready for shipping" ? bottleGreen : bottleGrey)}
alt={`Status: ${dewar.status}`}
style={{ width: '40px', height: '40px', marginBottom: '4px' }}
/>
<Typography variant="caption" sx={{ fontSize: '12px' }} color="textSecondary">
{dewar.ready_date ? `Ready: ${new Date(dewar.ready_date).toLocaleDateString()}` : 'N/A'}
</Typography>
</Box>
<ArrowForwardIcon sx={{ margin: '0 8px', fontSize: '40px', alignSelf: 'center' }} />
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
<AirplanemodeActiveIcon
sx={{
color: shippingStatusMap[dewar.shippingStatus || ""] || "grey",
fontSize: '40px',
marginBottom: '4px'
}}
/>
<Typography variant="caption" sx={{ fontSize: '12px' }} color="textSecondary">
{dewar.shipping_date ? `Shipped: ${new Date(dewar.shipping_date).toLocaleDateString()}` : 'N/A'}
</Typography>
</Box>
<ArrowForwardIcon sx={{ margin: '0 8px', fontSize: '40px', alignSelf: 'center' }} />
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
<StoreIcon
sx={{
color: arrivalStatusMap[dewar.arrivalStatus || ""] || "grey",
fontSize: '40px',
marginBottom: '4px'
}}
/>
<Typography variant="caption" sx={{ fontSize: '12px' }} color="textSecondary">
{dewar.arrival_date ? `Arrived: ${new Date(dewar.arrival_date).toLocaleDateString()}` : 'N/A'}
</Typography>
</Box>
{/* Delete button if the dewar is selected */}
{localSelectedDewar?.tracking_number === dewar.tracking_number && (
<Button
onClick={handleDeleteDewar}
color="error"
sx={{
minWidth: '40px',
height: '40px',
marginLeft: 2,
padding: 0,
alignSelf: 'center'
}}
title="Delete Dewar"
>
<DeleteIcon />
</Button>
)}
</Box>
</Button>
))}
</Stack>
</Box>
);
};
export default ShipmentDetails;