Connected frontend new contact and new address to backend

This commit is contained in:
GotthardG
2024-10-27 18:14:50 +01:00
parent 2a4f2d1d85
commit e5073eacb8
4 changed files with 286 additions and 130 deletions

View File

@ -3,6 +3,9 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi import HTTPException, status from fastapi import HTTPException, status
from pydantic import BaseModel from pydantic import BaseModel
from typing import List, Optional from typing import List, Optional
import logging
logging.basicConfig(level=logging.INFO)
app = FastAPI() app = FastAPI()
@ -28,6 +31,9 @@ class Address(BaseModel):
zipcode: str zipcode: str
country: str country: str
class Proposal(BaseModel):
id: int
number: str
class Dewar(BaseModel): class Dewar(BaseModel):
id: str id: str
@ -52,7 +58,7 @@ class Shipment(BaseModel):
shipment_date: str shipment_date: str
shipment_status: str shipment_status: str
contact_person: List[ContactPerson] contact_person: List[ContactPerson]
proposal_number: Optional[str] = None proposal_number: List[Proposal]
return_address: List[Address] return_address: List[Address]
comments: Optional[str] = None comments: Optional[str] = None
dewars: List[Dewar] dewars: List[Dewar]
@ -60,9 +66,15 @@ class Shipment(BaseModel):
def get_number_of_dewars(self) -> int: def get_number_of_dewars(self) -> int:
return len(self.dewars) return len(self.dewars)
def get_shipment_contact_persons(self) -> str: def get_shipment_contact_persons(self) -> List[ContactPerson]:
return self.contact_person return self.contact_person
def get_shipment_return_addresses(self) -> List[Address]:
return self.return_address
def get_proposals(self) -> List[Proposal]:
return self.proposal_number
class Config: class Config:
orm_mode = True orm_mode = True
@ -143,33 +155,62 @@ dewars = [
qrcode='QR123DEWAR003' qrcode='QR123DEWAR003'
), ),
] ]
# Example: Attach a specific Dewar by its id to a shipment
specific_dewar_id = 'DEWAR003' # The ID of the Dewar you want to attach
# Find the Dewar with the matching id # Proposal data inspired by the Lord of the Rings
specific_dewar = next((dewar for dewar in dewars if dewar.id == specific_dewar_id), None) proposals = [
Proposal(id=1, number="PROPOSAL-FRODO-001"), # "The Quest for the Ring"
Proposal(id=2, number="PROPOSAL-GANDALF-002"), # "The Fellowship's Journey"
Proposal(id=3, number="PROPOSAL-ARAGORN-003"), # "Return of the King"
Proposal(id=4, number="PROPOSAL-SAURON-004"), # "The Dark Lord's Plot"
Proposal(id=5, number="PROPOSAL-MORDOR-005"), # "The Road to Mount Doom"
]
# Since shipments need dewars, define them afterward # Example: Attach specific Dewars by their ids to shipments
specific_dewar_ids1 = ['DEWAR003'] # The IDs of the Dewars you want to attach to the first shipment
specific_dewar_ids2 = ['DEWAR001', 'DEWAR002'] # The IDs of the Dewars you want to attach to the second shipment
# Find the Dewars with the matching ids
specific_dewars1 = [dewar for dewar in dewars if dewar.id in specific_dewar_ids1]
specific_dewars2 = [dewar for dewar in dewars if dewar.id in specific_dewar_ids2]
# Define shipments with the selected Dewars
shipments = [ shipments = [
Shipment( Shipment(
shipment_id='SHIPMORDOR', shipment_id='SHIPMORDOR',
shipment_date='2024-10-10', shipment_date='2024-10-10',
shipment_name='Shipment example test', shipment_name='Shipment from Mordor',
shipment_status='Delivered', shipment_status='Delivered',
contact_person=[contacts[1]], contact_person=[contacts[1]],
proposal_number='PROJ001', proposal_number=[proposals[1]],
return_address=[return_addresses[0]], return_address=[return_addresses[0]],
comments='Handle with care', comments='Handle with care',
dewars=[specific_dewar] # Taking all dewars as an example dewars=specific_dewars1 # Attach specific Dewars for this shipment
),
Shipment(
shipment_id='SHIPMORDOR2',
shipment_date='2024-10-24',
shipment_name='Shipment from Mordor',
shipment_status='In Transit',
contact_person=[contacts[3]],
proposal_number=[proposals[2]],
return_address=[return_addresses[1]], # Changed index to a valid one
comments='Contains the one ring',
dewars=specific_dewars2 # Attach specific Dewars for this shipment
) )
] ]
@app.get("/contacts", response_model=List[ContactPerson]) @app.get("/contacts", response_model=List[ContactPerson])
async def get_contacts(): async def get_contacts():
return contacts return contacts
@app.get("/return_addresses", response_model=List[Address])
async def get_return_addresses():
return return_addresses
@app.get("/proposals", response_model=List[Proposal])
async def get_proposals():
return proposals
@app.get("/shipments", response_model=List[Shipment]) @app.get("/shipments", response_model=List[Shipment])
async def get_shipments(): async def get_shipments():
@ -204,3 +245,31 @@ async def create_shipment(shipment: Shipment):
shipments.append(shipment) shipments.append(shipment)
return shipment return shipment
# Creation of a new contact
@app.post("/contacts", response_model=ContactPerson, status_code=status.HTTP_201_CREATED)
async def create_contact(contact: ContactPerson):
logging.info(f"Received contact creation request: {contact}")
# Check for duplicate contact by email (or other unique fields)
if any(c.email == contact.email for c in contacts):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Contact with this email already exists."
)
contacts.append(contact)
return contact
# Creation of a return address
@app.post("/return_addresses", response_model=Address, status_code=status.HTTP_201_CREATED)
async def create_return_address(address: Address):
logging.info(f"Received contact creation request: {address}")
# Check for duplicate address by city
if any(a.city == address.city for a in return_addresses):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Address in this city already exists."
)
return_addresses.append(address)
return address

View File

@ -1,17 +1,25 @@
import * as React from 'react'; import * as React from 'react';
import { Box, Button, TextField, Typography, Select, MenuItem, Stack, FormControl, InputLabel } from '@mui/material'; import { Box, Button, TextField, Typography, Select, MenuItem, Stack, FormControl, InputLabel } from '@mui/material';
import { SelectChangeEvent } from '@mui/material'; import { SelectChangeEvent } from '@mui/material';
import { Shipment, ContactPerson, Proposal, Address } from '../types.ts'; // Adjust import paths as necessary
import { SxProps } from '@mui/material'; import { SxProps } from '@mui/material';
import {useEffect} from "react"; import { useEffect } from "react";
import {DefaultService} from "../../openapi"; import { ContactPerson, Address, Proposal, DefaultService, OpenAPI } from "../../openapi";
// Define the Shipment interface (example; adjust according to your types)
interface Shipment {
shipment_name: string;
contact_person: ContactPerson[];
proposal_number: string;
return_address: Address[];
comments: string;
}
// Define the ShipmentFormProps interface
interface ShipmentFormProps { interface ShipmentFormProps {
newShipment: Shipment; newShipment: Shipment;
setNewShipment: React.Dispatch<React.SetStateAction<Shipment>>; setNewShipment: React.Dispatch<React.SetStateAction<Shipment>>;
handleSaveShipment: () => void; handleSaveShipment: () => void;
contactPersons: ContactPerson[]; proposals: Proposal[]; // Define proposals type
proposals: Proposal[];
returnAddresses: Address[]; returnAddresses: Address[];
sx?: SxProps; sx?: SxProps;
} }
@ -20,11 +28,11 @@ const ShipmentForm: React.FC<ShipmentFormProps> = ({
newShipment, newShipment,
setNewShipment, setNewShipment,
handleSaveShipment, handleSaveShipment,
contactPersons,
proposals,
returnAddresses,
sx = {}, sx = {},
}) => { }) => {
const [contactPersons, setContactPersons] = React.useState<ContactPerson[]>([]); // State to hold contact persons
const [returnAddresses, setReturnAddresses] = React.useState<Address[]>([]); // Renamed for consistency
const [proposals, setProposals] = React.useState<Proposal[]>([]);
const [isCreatingContactPerson, setIsCreatingContactPerson] = React.useState(false); const [isCreatingContactPerson, setIsCreatingContactPerson] = React.useState(false);
const [isCreatingReturnAddress, setIsCreatingReturnAddress] = React.useState(false); const [isCreatingReturnAddress, setIsCreatingReturnAddress] = React.useState(false);
const [newContactPerson, setNewContactPerson] = React.useState({ const [newContactPerson, setNewContactPerson] = React.useState({
@ -33,18 +41,65 @@ const ShipmentForm: React.FC<ShipmentFormProps> = ({
phone: '', phone: '',
email: '', email: '',
}); });
const [newReturnAddress, setNewReturnAddress] = React.useState(''); const [newReturnAddress, setNewReturnAddress] = React.useState<Address>({
street: '',
city: '',
zipcode: '',
country: '',
});
const [errorMessage, setErrorMessage] = React.useState<string | null>(null); // For error handling
useEffect(() => {
OpenAPI.BASE = 'http://127.0.0.1:8000'; // Set the base URL for OpenAPI
const getContacts = async () => {
console.log('Trying to fetch some contacts');
try {
const c: ContactPerson[] = await DefaultService.getContactsContactsGet(); // Fetch contacts
setContactPersons(c);
} catch (err) {
console.error('Failed to fetch contact persons:', err);
setErrorMessage('Failed to load contact persons. Please try again later.');
}
};
const getAddresses = async () => {
console.log('Trying to fetch some return addresses');
try {
const a: Address[] = await DefaultService.getReturnAddressesReturnAddressesGet(); // Fetch addresses
setReturnAddresses(a);
} catch (err) {
console.error('Failed to fetch return addresses:', err);
setErrorMessage('Failed to load return addresses. Please try again later.');
}
};
const getProposals = async () => {
try {
const p: Proposal[] = await DefaultService.getProposalsProposalsGet();
console.log('Fetched Proposals:', p); // Debug log to check if proposals are being fetched
setProposals(p);
} catch (err) {
console.error('Error fetching proposals:', err); // Log the error
setErrorMessage('Failed to load proposals. Please try again later.');
}
};
getContacts();
getAddresses();
getProposals();
}, []);
const handleContactPersonChange = (event: SelectChangeEvent) => { const handleContactPersonChange = (event: SelectChangeEvent) => {
const value = event.target.value; const value = event.target.value;
if (value === 'new') { if (value === 'new') {
setIsCreatingContactPerson(true); setIsCreatingContactPerson(true);
setNewShipment({ ...newShipment, contact_person: [] }); // Set to empty array for new person setNewShipment({ ...newShipment, contact_person: [] }); // Reset for new person
} else { } else {
setIsCreatingContactPerson(false); setIsCreatingContactPerson(false);
const selectedPerson = contactPersons.find((person) => person.lastname === value) || null; const selectedPerson = contactPersons.find((person) => person.lastname === value) || null;
if (selectedPerson) { if (selectedPerson) {
setNewShipment({ ...newShipment, contact_person: [selectedPerson] }); // Wrap in array setNewShipment({ ...newShipment, contact_person: [selectedPerson] }); // Set selected person
} }
} }
}; };
@ -53,33 +108,61 @@ const ShipmentForm: React.FC<ShipmentFormProps> = ({
const value = event.target.value; const value = event.target.value;
if (value === 'new') { if (value === 'new') {
setIsCreatingReturnAddress(true); setIsCreatingReturnAddress(true);
setNewShipment({ ...newShipment, return_address: [] }); // Set to empty array for new address setNewShipment({ ...newShipment, return_address: [] }); // Reset for new address
} else { } else {
setIsCreatingReturnAddress(false); setIsCreatingReturnAddress(false);
const selectedAddress = returnAddresses.find((address) => address.address === value); const selectedAddress = returnAddresses.find((address) => address.city === value); // Match by a unique ID
if (selectedAddress) { if (selectedAddress) {
setNewShipment({ ...newShipment, return_address: [selectedAddress] }); // Wrap in array of Address setNewShipment({ ...newShipment, return_address: [selectedAddress] }); // Set selected address
} }
} }
}; };
const handleProposalChange = (event: SelectChangeEvent) => {
const selectedProposal = event.target.value;
console.log('Selected Proposal:', selectedProposal); // Corrected log statement
setNewShipment({ ...newShipment, proposal_number: selectedProposal });
};
const handleNewReturnAddressChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setNewReturnAddress((prev) => ({
...prev,
[name]: value,
}));
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target; const { name, value } = e.target;
setNewShipment((prev) => ({ ...prev, [name]: value })); setNewShipment((prev) => ({ ...prev, [name]: value }));
}; };
const handleSaveNewContactPerson = () => { const handleSaveNewReturnAddress = async () => {
// Add logic to save the new contact person OpenAPI.BASE = 'http://127.0.0.1:8000';
console.log('Saving new contact person:', newContactPerson);
setIsCreatingContactPerson(false); if (!newReturnAddress.street || !newReturnAddress.city || !newReturnAddress.zipcode || !newReturnAddress.country) {
setNewContactPerson({ firstName: '', lastName: '', phone: '', email: '' }); // Reset fields setErrorMessage('All fields are required.');
return;
}
const payload = {
street: newReturnAddress.street.trim(),
city: newReturnAddress.city.trim(),
zipcode: newReturnAddress.zipcode.trim(),
country: newReturnAddress.country.trim(),
}; };
const handleSaveNewReturnAddress = () => { try {
// Add logic to save the new return address const a: Address = await DefaultService.createReturnAddressReturnAddressesPost(payload);
console.log('Saving new return address:', newReturnAddress); setReturnAddresses([...returnAddresses, a]);
setErrorMessage(null);
} catch (err) {
console.error('Failed to create a new return address:', err);
setErrorMessage('Failed to create a new return address. Please try again later.');
}
setNewReturnAddress({ street: '', city: '', zipcode: '', country: '' });
setIsCreatingReturnAddress(false); setIsCreatingReturnAddress(false);
setNewReturnAddress(''); // Reset field
}; };
return ( return (
@ -96,6 +179,7 @@ const ShipmentForm: React.FC<ShipmentFormProps> = ({
<Typography variant="h6" sx={{ marginBottom: 2 }}> <Typography variant="h6" sx={{ marginBottom: 2 }}>
Create Shipment Create Shipment
</Typography> </Typography>
{errorMessage && <Typography color="error">{errorMessage}</Typography>}
<Stack spacing={2}> <Stack spacing={2}>
<TextField <TextField
label="Shipment Name" label="Shipment Name"
@ -111,12 +195,9 @@ const ShipmentForm: React.FC<ShipmentFormProps> = ({
onChange={handleContactPersonChange} onChange={handleContactPersonChange}
displayEmpty displayEmpty
> >
<MenuItem value="">
<em>Select a Contact Person</em>
</MenuItem>
{contactPersons.map((person) => ( {contactPersons.map((person) => (
<MenuItem key={person.id} value={person.lastname}> <MenuItem key={person.lastname + person.firstname} value={person.lastname}>
{person.lastname} {`${person.lastname}, ${person.firstname}`}
</MenuItem> </MenuItem>
))} ))}
<MenuItem value="new"> <MenuItem value="new">
@ -124,51 +205,13 @@ const ShipmentForm: React.FC<ShipmentFormProps> = ({
</MenuItem> </MenuItem>
</Select> </Select>
</FormControl> </FormControl>
{isCreatingContactPerson && (
<>
<TextField
label="First Name"
name="firstName"
value={newContactPerson.firstName}
onChange={(e) => setNewContactPerson({ ...newContactPerson, firstName: e.target.value })}
fullWidth
/>
<TextField
label="Last Name"
name="lastName"
value={newContactPerson.lastName}
onChange={(e) => setNewContactPerson({ ...newContactPerson, lastName: e.target.value })}
fullWidth
/>
<TextField
label="Phone"
name="phone"
value={newContactPerson.phone}
onChange={(e) => setNewContactPerson({ ...newContactPerson, phone: e.target.value })}
fullWidth
/>
<TextField
label="Email"
name="email"
value={newContactPerson.email}
onChange={(e) => setNewContactPerson({ ...newContactPerson, email: e.target.value })}
fullWidth
/>
<Button variant="contained" color="primary" onClick={handleSaveNewContactPerson}>
Save New Contact Person
</Button>
</>
)}
<FormControl fullWidth> <FormControl fullWidth>
<InputLabel>Proposal Number</InputLabel> <InputLabel>Proposal Number</InputLabel>
<Select <Select
value={newShipment.proposal_number || ''} value={newShipment.proposal_number || ''}
onChange={(e) => setNewShipment({ ...newShipment, proposal_number: e.target.value })} onChange={handleProposalChange}
displayEmpty displayEmpty
> >
<MenuItem value="">
<em>Select a Proposal Number</em>
</MenuItem>
{proposals.map((proposal) => ( {proposals.map((proposal) => (
<MenuItem key={proposal.id} value={proposal.number}> <MenuItem key={proposal.id} value={proposal.number}>
{proposal.number} {proposal.number}
@ -179,16 +222,13 @@ const ShipmentForm: React.FC<ShipmentFormProps> = ({
<FormControl fullWidth> <FormControl fullWidth>
<InputLabel>Return Address</InputLabel> <InputLabel>Return Address</InputLabel>
<Select <Select
value={newShipment.return_address?.[0]?.address || ''} // Access first return address's address value={newShipment.return_address?.[0]?.city || ''}
onChange={handleReturnAddressChange} onChange={handleReturnAddressChange}
displayEmpty displayEmpty
> >
<MenuItem value="">
<em>Select a Return Address</em>
</MenuItem>
{returnAddresses.map((address) => ( {returnAddresses.map((address) => (
<MenuItem key={address.id} value={address.address}> <MenuItem key={address.city} value={address.city}>
{address.address} {`${address.street}, ${address.city}, ${address.zipcode}, ${address.country}`}
</MenuItem> </MenuItem>
))} ))}
<MenuItem value="new"> <MenuItem value="new">
@ -199,9 +239,31 @@ const ShipmentForm: React.FC<ShipmentFormProps> = ({
{isCreatingReturnAddress && ( {isCreatingReturnAddress && (
<> <>
<TextField <TextField
label="New Return Address" label="Street"
value={newReturnAddress} name="street"
onChange={(e) => setNewReturnAddress(e.target.value)} value={newReturnAddress.street}
onChange={handleNewReturnAddressChange}
fullWidth
/>
<TextField
label="City"
name="city"
value={newReturnAddress.city}
onChange={handleNewReturnAddressChange}
fullWidth
/>
<TextField
label="Zip Code"
name="zipcode"
value={newReturnAddress.zipcode}
onChange={handleNewReturnAddressChange}
fullWidth
/>
<TextField
label="Country"
name="country"
value={newReturnAddress.country}
onChange={handleNewReturnAddressChange}
fullWidth fullWidth
/> />
<Button variant="contained" color="primary" onClick={handleSaveNewReturnAddress}> <Button variant="contained" color="primary" onClick={handleSaveNewReturnAddress}>

View File

@ -5,7 +5,7 @@ import AddIcon from '@mui/icons-material/Add';
import DeleteIcon from '@mui/icons-material/Delete'; // Import delete icon import DeleteIcon from '@mui/icons-material/Delete'; // Import delete icon
import UploadFileIcon from '@mui/icons-material/UploadFile'; // Import the upload icon import UploadFileIcon from '@mui/icons-material/UploadFile'; // Import the upload icon
import UploadDialog from './UploadDialog.tsx'; // Import the UploadDialog component import UploadDialog from './UploadDialog.tsx'; // Import the UploadDialog component
import {Shipment} from '../types.ts'; // Ensure Shipment type is correctly imported //import {Shipment} from '../types.ts'; // Ensure Shipment type is correctly imported
import { SxProps } from '@mui/material'; import { SxProps } from '@mui/material';
import bottleGrey from '../assets/icons/bottle-svgrepo-com-grey.svg'; import bottleGrey from '../assets/icons/bottle-svgrepo-com-grey.svg';
import bottleYellow from '../assets/icons/bottle-svgrepo-com-yellow.svg'; import bottleYellow from '../assets/icons/bottle-svgrepo-com-yellow.svg';
@ -13,17 +13,17 @@ import bottleGreen from '../assets/icons/bottle-svgrepo-com-green.svg';
import bottleRed from '../assets/icons/bottle-svgrepo-com-red.svg'; import bottleRed from '../assets/icons/bottle-svgrepo-com-red.svg';
import {Shipment_Input, DefaultService, OpenAPI} from "../../openapi"; import {Shipment_Input, DefaultService, OpenAPI} from "../../openapi";
interface ShipmentPanelProps { //interface ShipmentPanelProps {
selectedPage: string; // selectedPage: string;
setIsCreatingShipment: Dispatch<SetStateAction<boolean>>; // setIsCreatingShipment: Dispatch<SetStateAction<boolean>>;
newShipment: Shipment; // Ensure this aligns with the Shipment type // newShipment: Shipment; // Ensure this aligns with the Shipment type
setNewShipment: Dispatch<SetStateAction<Shipment>>; // setNewShipment: Dispatch<SetStateAction<Shipment>>;
selectShipment: (shipment: Shipment | null) => void; // Allow null for deselection // selectShipment: (shipment: Shipment | null) => void; // Allow null for deselection
sx?: SxProps; // Optional sx prop for styling // sx?: SxProps; // Optional sx prop for styling
} //}
const ShipmentPanel: React.FC<ShipmentPanelProps> = ({ const ShipmentPanel: React.FC<ShipmentPanelProps> = ({
//setIsCreatingShipment, setIsCreatingShipment,
//newShipment, //newShipment,
//setNewShipment, //setNewShipment,
//selectedPage, //selectedPage,
@ -53,18 +53,16 @@ const ShipmentPanel: React.FC<ShipmentPanelProps> = ({
}; };
useEffect(() => { useEffect(() => {
OpenAPI.BASE='http://127.0.0.1:8000' OpenAPI.BASE = 'http://127.0.0.1:8000';
const fetchShipments = async () => { const fetchShipments = async () => {
console.log('trying to fetch some shipments'); console.log('trying to fetch some shipments');
try { try {
DefaultService.getShipmentsShipmentsGet().then((s : Shipment_Input[]) => { // Await the response from the service call
const s: Shipment_Input[] = await DefaultService.getShipmentsShipmentsGet();
// Set the shipments state with the fetched data
setShipments(s); setShipments(s);
});
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const data = await response.json();
setShipments(data.shipments);
} catch (error) { } catch (error) {
// If an error occurs, set the error message
console.error('Failed to fetch shipments:', error); console.error('Failed to fetch shipments:', error);
setError("Failed to fetch shipments. Please try again later."); setError("Failed to fetch shipments. Please try again later.");
} }
@ -100,7 +98,7 @@ const ShipmentPanel: React.FC<ShipmentPanelProps> = ({
variant="contained" variant="contained"
color="primary" color="primary"
startIcon={<AddIcon />} startIcon={<AddIcon />}
//onClick={() => { onClick={() => {
// setNewShipment({ // setNewShipment({
// shipment_id: '', // Ensure this matches the Shipment type // shipment_id: '', // Ensure this matches the Shipment type
// shipment_name: '', // shipment_name: '',
@ -113,8 +111,8 @@ const ShipmentPanel: React.FC<ShipmentPanelProps> = ({
// proposal_number: undefined, // Optional property // proposal_number: undefined, // Optional property
// comments: '', // Optional property // comments: '', // Optional property
// }); // });
// setIsCreatingShipment(true); setIsCreatingShipment(true);
//}} }}
sx={{ marginBottom: 2, padding: '10px 16px' }} sx={{ marginBottom: 2, padding: '10px 16px' }}
> >
Create Shipment Create Shipment

View File

@ -1,41 +1,68 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import ShipmentPanel from '../components/ShipmentPanel'; import ShipmentPanel from '../components/ShipmentPanel';
import { Shipment } from '../types'; import ShipmentForm from '../components/ShipmentForm'; // Import the ShipmentForm component
import { Shipment, ContactPerson, Proposal, Address } from '../types'; // Ensure these types are defined
const ShipmentView: React.FC = () => { const ShipmentView: React.FC = () => {
//const [isCreatingShipment, setIsCreatingShipment] = useState(false); const [isCreatingShipment, setIsCreatingShipment] = useState(false); // State to track if the form is open
//const [newShipment, setNewShipment] = useState<Shipment>({ const [newShipment, setNewShipment] = useState<Shipment>({
// shipment_id: '', shipment_id: '',
// shipment_name: '', shipment_name: '',
// shipment_status: '', shipment_status: '',
// number_of_dewars: 0, number_of_dewars: 0,
// shipment_date: '', shipment_date: '',
// contact_person: null, contact_person: null,
// dewars: [], dewars: [],
// return_address: [], return_address: [],
// proposal_number: undefined, proposal_number: undefined,
// comments: '', comments: '',
//}); });
// Dummy data for contact persons, proposals, and addresses
const contactPersons: ContactPerson[] = [
// Populate with contact person objects
];
const proposals: Proposal[] = [
// Populate with proposal objects
];
const returnAddresses: Address[] = [
// Populate with return address objects
];
const selectShipment = (shipment: Shipment | null) => { const selectShipment = (shipment: Shipment | null) => {
console.log('Selected Shipment:', shipment); console.log('Selected Shipment:', shipment);
// Additional logic for selected shipment // Additional logic for selected shipment
}; };
const handleSaveShipment = () => {
console.log('Saving shipment:', newShipment);
setIsCreatingShipment(false); // Close the form after saving
// Add logic to save the shipment
};
return ( return (
<div style={{ display: 'flex', padding: '16px' }}> <div style={{ display: 'flex', padding: '16px' }}>
{/* Shipment Panel on the left side */} {/* Shipment Panel on the left side */}
<ShipmentPanel <ShipmentPanel
selectedPage="shipments" selectedPage="shipments"
//setIsCreatingShipment={setIsCreatingShipment} setIsCreatingShipment={setIsCreatingShipment} // Pass the state setter
//newShipment={newShipment}
//setNewShipment={setNewShipment}
selectShipment={selectShipment} selectShipment={selectShipment}
sx={{ width: '300px' }} // Adjust width as needed sx={{ width: '300px' }} // Adjust width as needed
/> />
{/* Additional content can go here */} {/* Conditional rendering of the ShipmentForm */}
<div style={{ marginLeft: '16px', flexGrow: 1 }}> <div style={{ marginLeft: '16px', flexGrow: 1 }}>
{/* Other components or information related to selected shipment can go here */} {isCreatingShipment ? (
<ShipmentForm
newShipment={newShipment}
setNewShipment={setNewShipment}
handleSaveShipment={handleSaveShipment}
contactPersons={contactPersons}
proposals={proposals}
returnAddresses={returnAddresses}
/>
) : (
<div> {/* Content when form is not open */} </div>
)}
</div> </div>
</div> </div>
); );