Better integration of sqlite3 database
This commit is contained in:
@ -2,35 +2,50 @@ import React from 'react';
|
||||
import { Box, Typography, Button, Stack, TextField } from '@mui/material';
|
||||
import QRCode from 'react-qr-code';
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import { Dewar, Shipment_Input, DefaultService } from "../../openapi";
|
||||
import { Dewar, DewarsService, ShipmentsService, ContactPerson, ApiError } from "../../openapi"; // Ensure ApiError is imported here
|
||||
import { SxProps } from "@mui/system";
|
||||
import CustomStepper from "./DewarStepper";
|
||||
import DewarDetails from './DewarDetails';
|
||||
|
||||
interface ShipmentDetailsProps {
|
||||
isCreatingShipment: boolean;
|
||||
selectedShipment: Shipment_Input;
|
||||
sx?: SxProps;
|
||||
selectedShipment: ShipmentsService | null;
|
||||
selectedDewar: Dewar | null;
|
||||
setSelectedDewar: React.Dispatch<React.SetStateAction<Dewar | null>>;
|
||||
setSelectedShipment: React.Dispatch<React.SetStateAction<Shipment_Input>>;
|
||||
sx?: SxProps;
|
||||
setSelectedShipment: React.Dispatch<React.SetStateAction<ShipmentsService | null>>;
|
||||
refreshShipments: () => void;
|
||||
defaultContactPerson?: ContactPerson;
|
||||
}
|
||||
|
||||
const ShipmentDetails: React.FC<ShipmentDetailsProps> = ({
|
||||
isCreatingShipment,
|
||||
sx,
|
||||
selectedShipment,
|
||||
selectedDewar,
|
||||
setSelectedDewar,
|
||||
setSelectedShipment,
|
||||
sx = {},
|
||||
refreshShipments,
|
||||
defaultContactPerson
|
||||
}) => {
|
||||
const [localSelectedDewar, setLocalSelectedDewar] = React.useState<Dewar | null>(null);
|
||||
const [isAddingDewar, setIsAddingDewar] = React.useState<boolean>(false);
|
||||
const [newDewar, setNewDewar] = React.useState<Partial<Dewar>>({
|
||||
dewar_name: '',
|
||||
});
|
||||
|
||||
// To reset localSelectedDewar when selectedShipment changes
|
||||
const initialNewDewarState: Partial<Dewar> = {
|
||||
dewar_name: '',
|
||||
tracking_number: '',
|
||||
number_of_pucks: 0,
|
||||
number_of_samples: 0,
|
||||
status: 'In preparation',
|
||||
ready_date: null,
|
||||
shipping_date: null,
|
||||
arrival_date: null,
|
||||
returning_date: null,
|
||||
qrcode: 'N/A'
|
||||
};
|
||||
|
||||
const [newDewar, setNewDewar] = React.useState<Partial<Dewar>>(initialNewDewarState);
|
||||
|
||||
React.useEffect(() => {
|
||||
setLocalSelectedDewar(null);
|
||||
}, [selectedShipment]);
|
||||
@ -39,8 +54,8 @@ const ShipmentDetails: React.FC<ShipmentDetailsProps> = ({
|
||||
console.log('ShipmentDetails - selectedShipment updated:', selectedShipment);
|
||||
}, [selectedShipment]);
|
||||
|
||||
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);
|
||||
const totalPucks = selectedShipment?.dewars?.reduce((acc, dewar) => acc + (dewar.number_of_pucks || 0), 0) || 0;
|
||||
const totalSamples = selectedShipment?.dewars?.reduce((acc, dewar) => acc + (dewar.number_of_samples || 0), 0) || 0;
|
||||
|
||||
const handleDewarSelection = (dewar: Dewar) => {
|
||||
const newSelection = localSelectedDewar?.id === dewar.id ? null : dewar;
|
||||
@ -50,18 +65,12 @@ const ShipmentDetails: React.FC<ShipmentDetailsProps> = ({
|
||||
|
||||
const handleDeleteDewar = async (dewarId: string) => {
|
||||
const confirmed = window.confirm('Are you sure you want to delete this dewar?');
|
||||
if (confirmed) {
|
||||
if (confirmed && selectedShipment) {
|
||||
try {
|
||||
console.log('Selected Shipment ID:', selectedShipment.shipment_id);
|
||||
console.log('Dewar ID to be deleted:', dewarId);
|
||||
|
||||
const updatedShipment = await DefaultService.removeDewarFromShipmentShipmentsShipmentIdRemoveDewarDewarIdDelete(
|
||||
selectedShipment.shipment_id, dewarId
|
||||
);
|
||||
|
||||
// Ensure state is updated with server response
|
||||
const updatedShipment = await ShipmentsService.removeDewarFromShipmentShipmentsShipmentIdRemoveDewarDewarIdDelete(selectedShipment.shipment_id, dewarId);
|
||||
setSelectedShipment(updatedShipment);
|
||||
setLocalSelectedDewar(null);
|
||||
refreshShipments();
|
||||
} catch (error) {
|
||||
console.error('Failed to delete dewar:', error);
|
||||
alert('Failed to delete dewar. Please try again.');
|
||||
@ -78,55 +87,42 @@ const ShipmentDetails: React.FC<ShipmentDetailsProps> = ({
|
||||
};
|
||||
|
||||
const handleAddDewar = async () => {
|
||||
if (selectedShipment && newDewar.dewar_name) {
|
||||
if (newDewar.dewar_name?.trim()) {
|
||||
try {
|
||||
const newDewarToPost: Dewar = {
|
||||
...newDewar as Dewar,
|
||||
dewar_name: newDewar.dewar_name.trim() || 'Unnamed Dewar',
|
||||
number_of_pucks: newDewar.number_of_pucks ?? 0,
|
||||
number_of_samples: newDewar.number_of_samples ?? 0,
|
||||
return_address: selectedShipment.return_address,
|
||||
contact_person: selectedShipment.contact_person,
|
||||
status: 'In preparation',
|
||||
qrcode: newDewar.qrcode || 'N/A',
|
||||
};
|
||||
...initialNewDewarState,
|
||||
...newDewar,
|
||||
dewar_name: newDewar.dewar_name.trim(),
|
||||
contact_person: selectedShipment?.contact_person,
|
||||
contact_person_id: selectedShipment?.contact_person?.id, // Adding contact_person_id
|
||||
return_address: selectedShipment?.return_address,
|
||||
return_address_id: selectedShipment?.return_address?.id, // Adding return_address_id
|
||||
} as Dewar;
|
||||
|
||||
// Create a new dewar
|
||||
const createdDewar = await DefaultService.createDewarDewarsPost(newDewarToPost);
|
||||
|
||||
console.log('Created Dewar:', createdDewar);
|
||||
|
||||
// Check IDs before calling backend
|
||||
console.log('Adding dewar to shipment:', {
|
||||
shipment_id: selectedShipment.shipment_id,
|
||||
dewar_id: createdDewar.id,
|
||||
});
|
||||
|
||||
// Make an API call to associate the dewar with the shipment
|
||||
const updatedShipment = await DefaultService.addDewarToShipmentShipmentsShipmentIdAddDewarPost(
|
||||
selectedShipment.shipment_id,
|
||||
createdDewar.id
|
||||
);
|
||||
|
||||
if (updatedShipment) {
|
||||
const createdDewar = await DewarsService.createDewarDewarsPost(newDewarToPost);
|
||||
if (createdDewar && selectedShipment) {
|
||||
const updatedShipment = await ShipmentsService.addDewarToShipmentShipmentsShipmentIdAddDewarPost(selectedShipment.shipment_id, createdDewar.id);
|
||||
setSelectedShipment(updatedShipment);
|
||||
} else {
|
||||
throw new Error('Failed to update shipment with new dewar');
|
||||
setIsAddingDewar(false);
|
||||
setNewDewar(initialNewDewarState);
|
||||
refreshShipments();
|
||||
}
|
||||
|
||||
setIsAddingDewar(false);
|
||||
setNewDewar({ dewar_name: '', tracking_number: '' });
|
||||
refreshShipments()
|
||||
|
||||
} catch (error) {
|
||||
alert('Failed to add dewar or update shipment. Please try again.');
|
||||
console.error('Error adding dewar or updating shipment:', error);
|
||||
if (error instanceof ApiError && error.body) {
|
||||
console.error('Validation errors:', error.body.detail); // Log specific validation errors
|
||||
} else {
|
||||
console.error('Unexpected error:', error);
|
||||
}
|
||||
alert('Failed to add dewar or update shipment. Please check the data and try again.');
|
||||
}
|
||||
} else {
|
||||
alert('Please fill in the Dewar Name');
|
||||
}
|
||||
};
|
||||
|
||||
const contactPerson = selectedShipment?.contact_person;
|
||||
|
||||
return (
|
||||
<Box sx={{ ...sx, padding: 2, textAlign: 'left' }}>
|
||||
{!localSelectedDewar && !isAddingDewar && (
|
||||
@ -159,11 +155,19 @@ const ShipmentDetails: React.FC<ShipmentDetailsProps> = ({
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Typography variant="h5">{selectedShipment.shipment_name}</Typography>
|
||||
<Typography variant="body1" color="textSecondary">Main contact person: {`${selectedShipment.contact_person[0].firstname} ${selectedShipment.contact_person[0].lastname}`}</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>
|
||||
{selectedShipment ? (
|
||||
<>
|
||||
<Typography variant="h5">{selectedShipment.shipment_name}</Typography>
|
||||
<Typography variant="body1" color="textSecondary">
|
||||
Main contact person: {contactPerson ? `${contactPerson.firstname} ${contactPerson.lastname}` : 'N/A'}
|
||||
</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>
|
||||
</>
|
||||
) : (
|
||||
<Typography variant="h5" color="error">No shipment selected</Typography>
|
||||
)}
|
||||
|
||||
{localSelectedDewar && !isAddingDewar && (
|
||||
<DewarDetails
|
||||
@ -172,17 +176,17 @@ const ShipmentDetails: React.FC<ShipmentDetailsProps> = ({
|
||||
setTrackingNumber={(value) => {
|
||||
setLocalSelectedDewar((prev) => (prev ? { ...prev, tracking_number: value as string } : prev));
|
||||
}}
|
||||
initialContactPersons={selectedShipment.contact_person}
|
||||
initialReturnAddresses={selectedShipment.return_address}
|
||||
defaultContactPerson={selectedShipment.contact_person[0]}
|
||||
defaultReturnAddress={selectedShipment.return_address[0]}
|
||||
shipmentId={selectedShipment.shipment_id}
|
||||
initialContactPersons={selectedShipment?.contact_person ? [selectedShipment.contact_person] : []}
|
||||
initialReturnAddresses={selectedShipment?.return_address ? [selectedShipment.return_address] : []}
|
||||
defaultContactPerson={contactPerson}
|
||||
defaultReturnAddress={selectedShipment?.return_address}
|
||||
shipmentId={selectedShipment?.shipment_id || ''}
|
||||
refreshShipments={refreshShipments}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Stack spacing={1}>
|
||||
{selectedShipment.dewars.map((dewar) => (
|
||||
{selectedShipment?.dewars?.map((dewar) => (
|
||||
<Button
|
||||
key={dewar.id}
|
||||
onClick={() => handleDewarSelection(dewar)}
|
||||
@ -197,14 +201,7 @@ const ShipmentDetails: React.FC<ShipmentDetailsProps> = ({
|
||||
backgroundColor: localSelectedDewar?.id === dewar.id ? '#f0f0f0' : '#fff',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginRight: 2,
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', marginRight: 2 }}>
|
||||
{dewar.qrcode ? (
|
||||
<QRCode value={dewar.qrcode} size={70} />
|
||||
) : (
|
||||
@ -230,7 +227,9 @@ const ShipmentDetails: React.FC<ShipmentDetailsProps> = ({
|
||||
<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>
|
||||
<Typography variant="body2">Contact Person: {`${dewar.contact_person[0].firstname} ${dewar.contact_person[0].lastname}`}</Typography>
|
||||
<Typography variant="body2">
|
||||
Contact Person: {dewar.contact_person?.firstname ? `${dewar.contact_person.firstname} ${dewar.contact_person.lastname}` : 'N/A'}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box sx={{
|
||||
@ -243,7 +242,7 @@ const ShipmentDetails: React.FC<ShipmentDetailsProps> = ({
|
||||
<CustomStepper dewar={dewar} />
|
||||
{localSelectedDewar?.id === dewar.id && (
|
||||
<Button
|
||||
onClick={() => handleDeleteDewar(dewar.id)} // <--- Pass the dewar ID here
|
||||
onClick={() => handleDeleteDewar(dewar.id)}
|
||||
color="error"
|
||||
sx={{
|
||||
minWidth: '40px',
|
||||
|
Reference in New Issue
Block a user