diff --git a/frontend/src/components/DewarStepper.tsx b/frontend/src/components/DewarStepper.tsx index edcef4d..f288021 100644 --- a/frontend/src/components/DewarStepper.tsx +++ b/frontend/src/components/DewarStepper.tsx @@ -4,7 +4,7 @@ import AirplanemodeActiveIcon from '@mui/icons-material/AirplanemodeActive'; import StoreIcon from '@mui/icons-material/Store'; import RecycleIcon from '@mui/icons-material/Restore'; import { Dewar, DewarsService } from "../../openapi"; -import { STATUS_TO_STEP, DewarStatus, getStatusStepIndex, determineIconColor } from './statusUtils'; // Utilities moved to a new file +import { DewarStatus, getStatusStepIndex, determineIconColor } from './statusUtils'; // Utilities moved to a new file const ICON_STYLE = { width: 24, height: 24 }; @@ -15,6 +15,7 @@ const BottleIcon: React.FC<{ fill: string }> = ({ fill }) => ( ); +// Define types for icons mapping. const ICONS: { [key: number]: React.ReactElement } = { 0: , 1: , @@ -24,6 +25,10 @@ const ICONS: { [key: number]: React.ReactElement } = { 5: , }; +interface StepIconContainerProps extends React.HTMLAttributes { + color: string; +} + const StepIconContainer: React.FC = ({ color, children, ...rest }) => (
{children} @@ -34,15 +39,18 @@ type StepIconComponentProps = { icon: number; dewar: Dewar; isSelected: boolean; + refreshShipments: () => void; } & StepIconProps; -const StepIconComponent = ({ icon, dewar, isSelected, ...props }: StepIconComponentProps) => { +const StepIconComponent = ({ icon, dewar, isSelected, refreshShipments, ...props }: StepIconComponentProps) => { const [anchorEl, setAnchorEl] = useState(null); + const handleIconEnter = (event: React.MouseEvent) => { if (isSelected && icon === 0) { setAnchorEl(event.currentTarget); } }; + const handleIconLeave = () => { setAnchorEl(null); }; @@ -57,7 +65,7 @@ const StepIconComponent = ({ icon, dewar, isSelected, ...props }: StepIconCompon number_of_pucks: dewar.number_of_pucks, number_of_samples: dewar.number_of_samples, status: status, - ready_date: status === 'Ready for Shipping' ? today : dewar.ready_date, + ready_date: status === 'Ready for Shipping' ? today : null, shipping_date: dewar.shipping_date, arrival_date: dewar.arrival_date, returning_date: dewar.returning_date, @@ -68,6 +76,7 @@ const StepIconComponent = ({ icon, dewar, isSelected, ...props }: StepIconCompon await DewarsService.updateDewarDewarsDewarIdPut(dewar.id || '', payload); setAnchorEl(null); + refreshShipments(); // Refresh shipments after status update } catch (error) { console.error('Failed to update dewar status:', error); alert('Failed to update dewar status. Please try again.'); @@ -100,7 +109,7 @@ const StepIconComponent = ({ icon, dewar, isSelected, ...props }: StepIconCompon onMouseLeave: handleIconLeave, }} > - {['Ready for Shipping'].map((status) => ( + {['In Preparation', 'Ready for Shipping'].map((status) => ( handleStatusChange(status as DewarStatus)}> {status} @@ -123,9 +132,10 @@ const steps = ['In-House', 'Transit', 'At SLS', 'Returned']; type CustomStepperProps = { dewar: Dewar; selectedDewarId: string | null; + refreshShipments: () => void; // Add refreshShipments prop } -const CustomStepper = ({ dewar, selectedDewarId }: CustomStepperProps) => { +const CustomStepper = ({ dewar, selectedDewarId, refreshShipments }: CustomStepperProps) => { const activeStep = getStatusStepIndex(dewar.status as DewarStatus); const isSelected = dewar.id === selectedDewarId; @@ -135,7 +145,7 @@ const CustomStepper = ({ dewar, selectedDewarId }: CustomStepperProps) => { {steps.map((label, index) => ( } + StepIconComponent={(stepProps) => } > {label} diff --git a/frontend/src/components/ShipmentDetails.tsx b/frontend/src/components/ShipmentDetails.tsx index b68f0c5..f5b7975 100644 --- a/frontend/src/components/ShipmentDetails.tsx +++ b/frontend/src/components/ShipmentDetails.tsx @@ -311,8 +311,7 @@ const ShipmentDetails: React.FC = ({ flexDirection: 'row', justifyContent: 'space-between' }}> - - + diff --git a/frontend/src/pages/ShipmentView.tsx b/frontend/src/pages/ShipmentView.tsx index e9a1c5a..a341483 100644 --- a/frontend/src/pages/ShipmentView.tsx +++ b/frontend/src/pages/ShipmentView.tsx @@ -4,6 +4,7 @@ import ShipmentPanel from '../components/ShipmentPanel'; import ShipmentDetails from '../components/ShipmentDetails'; import ShipmentForm from '../components/ShipmentForm'; import { Dewar, OpenAPI, ContactPerson, ShipmentsService } from '../../openapi'; +import useShipments from '../hooks/useShipments'; type ShipmentViewProps = React.PropsWithChildren>; @@ -11,42 +12,10 @@ const API_BASE_URL = 'http://127.0.0.1:8000'; OpenAPI.BASE = API_BASE_URL; // Setting API base URL const ShipmentView: React.FC = () => { - const [isCreatingShipment, setIsCreatingShipment] = useState(false); + const { shipments, error, defaultContactPerson, fetchAndSetShipments } = useShipments(); const [selectedShipment, setSelectedShipment] = useState(null); - const [selectedDewar, setSelectedDewar] = useState(null); - const [shipments, setShipments] = useState([]); - const [error, setError] = useState(null); - const [defaultContactPerson, setDefaultContactPerson] = useState(); + const [selectedDewar, setSelectedDewar] = useState(null);const [isCreatingShipment, setIsCreatingShipment] = useState(false); - // Function to fetch and set shipments - const fetchAndSetShipments = async () => { - try { - const shipmentsData: ShipmentsService[] = await ShipmentsService.fetchShipmentsShipmentsGet(); - shipmentsData.sort((a, b) => new Date(b.shipment_date).getTime() - new Date(a.shipment_date).getTime()); - setShipments(shipmentsData); - console.log('Fetched and set shipments:', shipmentsData); - } catch (error) { - console.error('Failed to fetch shipments:', error); - setError('Failed to fetch shipments. Please try again later.'); - } - }; - - // Function to fetch the default contact person - const fetchDefaultContactPerson = async () => { - try { - const contacts: ContactPerson[] = await ShipmentsService.getShipmentContactPersonsShipmentsContactPersonsGet(); - setDefaultContactPerson(contacts[0]); - } catch (error) { - console.error('Failed to fetch contact persons:', error); - setError('Failed to load contact persons. Please try again later.'); - } - }; - - // Use effects to fetch data on component mount - useEffect(() => { - fetchAndSetShipments(); - fetchDefaultContactPerson(); - }, []); useEffect(() => { console.log('Updated shipments:', shipments);