added contacts and addresses manager

This commit is contained in:
GotthardG
2024-11-04 21:31:01 +01:00
parent 689145150a
commit 4e76db4c9f
11 changed files with 467 additions and 10 deletions
+138
View File
@@ -0,0 +1,138 @@
import * as React from 'react';
import axios from 'axios';
import {
Container, Typography, List, ListItem, IconButton, TextField, Box, ListItemText, ListItemSecondaryAction
} from '@mui/material';
import DeleteIcon from '@mui/icons-material/Delete';
import EditIcon from '@mui/icons-material/Edit';
import SaveIcon from '@mui/icons-material/Save';
import AddIcon from '@mui/icons-material/Add';
interface Address {
id: number;
street: string;
city: string;
zipcode: string;
country: string;
}
const AddressManager: React.FC = () => {
const [addresses, setAddresses] = React.useState<Address[]>([]);
const [newAddress, setNewAddress] = React.useState<Partial<Address>>({
id: 0,
street: '',
city: '',
zipcode: '',
country: '',
});
const [editAddressId, setEditAddressId] = React.useState<number | null>(null);
const [errorMessage, setErrorMessage] = React.useState<string | null>(null);
React.useEffect(() => {
const fetchAddresses = async () => {
try {
const response = await axios.get('http://127.0.0.1:8000/addresses');
if (Array.isArray(response.data)) {
setAddresses(response.data);
} else {
setErrorMessage('Failed to load addresses. Expected an array of addresses.');
}
} catch (error) {
console.error('Failed to fetch addresses', error);
setErrorMessage('Failed to load addresses. Please try again later.');
}
};
fetchAddresses();
}, []);
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = event.target;
setNewAddress({ ...newAddress, [name]: value });
};
const handleAddOrUpdateAddress = async () => {
if (editAddressId !== null) {
// Update address
try {
await axios.put(`http://127.0.0.1:8000/addresses/${editAddressId}`, newAddress);
setAddresses(addresses.map(address => address.id === editAddressId ? { ...address, ...newAddress } : address));
setEditAddressId(null);
setNewAddress({ street: '', city: '', zipcode: '', country: '' });
setErrorMessage(null);
} catch (error) {
console.error('Failed to update address', error);
setErrorMessage('Failed to update address. Please try again later.');
}
} else {
// Add new address
try {
const response = await axios.post('http://127.0.0.1:8000/addresses', newAddress);
setAddresses([...addresses, response.data]);
setNewAddress({ street: '', city: '', zipcode: '', country: '' });
setErrorMessage(null);
} catch (error) {
console.error('Failed to add address', error);
setErrorMessage('Failed to add address. Please try again later.');
}
}
};
const handleDeleteAddress = async (id: number) => {
try {
await axios.delete(`http://127.0.0.1:8000/addresses/${id}`);
setAddresses(addresses.filter(address => address.id !== id));
setErrorMessage(null);
} catch (error) {
console.error('Failed to delete address', error);
setErrorMessage('Failed to delete address. Please try again later.');
}
};
const handleEditAddress = (address: Address) => {
setEditAddressId(address.id);
setNewAddress(address);
};
return (
<Container>
<Typography variant="h4" gutterBottom>
Addresses Management
</Typography>
<Box mb={3} display="flex" justifyContent="center" alignItems="center">
<TextField label="Street" name="street" value={newAddress.street || ''} onChange={handleInputChange} />
<TextField label="City" name="city" value={newAddress.city || ''} onChange={handleInputChange} />
<TextField label="Zipcode" name="zipcode" value={newAddress.zipcode || ''} onChange={handleInputChange} />
<TextField label="Country" name="country" value={newAddress.country || ''} onChange={handleInputChange} />
<IconButton color="primary" onClick={handleAddOrUpdateAddress}>
{editAddressId !== null ? <SaveIcon /> : <AddIcon />}
</IconButton>
</Box>
{errorMessage && <Typography color="error">{errorMessage}</Typography>}
<List>
{addresses.length > 0 ? (
addresses.map((address) => (
<ListItem key={address.id} button>
<ListItemText
primary={`${address.street}, ${address.city}`}
secondary={`${address.zipcode} - ${address.country}`}
/>
<ListItemSecondaryAction>
<IconButton edge="end" color="primary" onClick={() => handleEditAddress(address)}>
<EditIcon />
</IconButton>
<IconButton edge="end" color="secondary" onClick={() => handleDeleteAddress(address.id)}>
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
))
) : (
<Typography>No addresses found</Typography>
)}
</List>
</Container>
);
};
export default AddressManager;
+138
View File
@@ -0,0 +1,138 @@
import * as React from 'react';
import axios from 'axios';
import {
Container, Typography, List, ListItem, IconButton, TextField, Box, ListItemText, ListItemSecondaryAction
} from '@mui/material';
import DeleteIcon from '@mui/icons-material/Delete';
import EditIcon from '@mui/icons-material/Edit';
import SaveIcon from '@mui/icons-material/Save';
import AddIcon from '@mui/icons-material/Add';
interface Contact {
id: number;
firstname: string;
lastname: string;
phone_number: string;
email: string;
}
const ContactsManager: React.FC = () => {
const [contacts, setContacts] = React.useState<Contact[]>([]);
const [newContact, setNewContact] = React.useState<Partial<Contact>>({
id: 0,
firstname: '',
lastname: '',
phone_number: '',
email: '',
});
const [editContactId, setEditContactId] = React.useState<number | null>(null);
const [errorMessage, setErrorMessage] = React.useState<string | null>(null);
React.useEffect(() => {
const fetchContacts = async () => {
try {
const response = await axios.get('http://127.0.0.1:8000/contacts');
if (Array.isArray(response.data)) {
setContacts(response.data);
} else {
setErrorMessage('Failed to load contacts. Expected an array of contacts.');
}
} catch (error) {
console.error('Failed to fetch contacts', error);
setErrorMessage('Failed to load contacts. Please try again later.');
}
};
fetchContacts();
}, []);
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = event.target;
setNewContact({ ...newContact, [name]: value });
};
const handleAddOrUpdateContact = async () => {
if (editContactId !== null) {
// Update contact
try {
await axios.put(`http://127.0.0.1:8000/contacts/${editContactId}`, newContact);
setContacts(contacts.map(contact => contact.id === editContactId ? { ...contact, ...newContact } : contact));
setEditContactId(null);
setNewContact({ firstname: '', lastname: '', phone_number: '', email: '' });
setErrorMessage(null);
} catch (error) {
console.error('Failed to update contact', error);
setErrorMessage('Failed to update contact. Please try again later.');
}
} else {
// Add new contact
try {
const response = await axios.post('http://127.0.0.1:8000/contacts', newContact);
setContacts([...contacts, response.data]);
setNewContact({ firstname: '', lastname: '', phone_number: '', email: '' });
setErrorMessage(null);
} catch (error) {
console.error('Failed to add contact', error);
setErrorMessage('Failed to add contact. Please try again later.');
}
}
};
const handleDeleteContact = async (id: number) => {
try {
await axios.delete(`http://127.0.0.1:8000/contacts/${id}`);
setContacts(contacts.filter(contact => contact.id !== id));
setErrorMessage(null);
} catch (error) {
console.error('Failed to delete contact', error);
setErrorMessage('Failed to delete contact. Please try again later.');
}
};
const handleEditContact = (contact: Contact) => {
setEditContactId(contact.id);
setNewContact(contact);
};
return (
<Container>
<Typography variant="h4" gutterBottom>
Contacts Management
</Typography>
<Box mb={3} display="flex" justifyContent="center" alignItems="center">
<TextField label="First Name" name="firstname" value={newContact.firstname || ''} onChange={handleInputChange} />
<TextField label="Last Name" name="lastname" value={newContact.lastname || ''} onChange={handleInputChange} />
<TextField label="Phone Number" name="phone_number" value={newContact.phone_number || ''} onChange={handleInputChange} />
<TextField label="Email" name="email" value={newContact.email || ''} onChange={handleInputChange} />
<IconButton color="primary" onClick={handleAddOrUpdateContact}>
{editContactId !== null ? <SaveIcon /> : <AddIcon />}
</IconButton>
</Box>
{errorMessage && <Typography color="error">{errorMessage}</Typography>}
<List>
{contacts.length > 0 ? (
contacts.map((contact) => (
<ListItem key={contact.id} button>
<ListItemText
primary={`${contact.firstname} ${contact.lastname}`}
secondary={`${contact.phone_number} - ${contact.email}`}
/>
<ListItemSecondaryAction>
<IconButton edge="end" color="primary" onClick={() => handleEditContact(contact)}>
<EditIcon />
</IconButton>
<IconButton edge="end" color="secondary" onClick={() => handleDeleteContact(contact.id)}>
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
))
) : (
<Typography>No contacts found</Typography>
)}
</List>
</Container>
);
};
export default ContactsManager;