This article will guide you through creating a Contacts Manager application in React, styled with Bootstrap and enhanced with Font Awesome icons. The application will allow you to add, edit, and delete contacts using modal dialogs.
Approach:
- Create a new React project using create-react-app.
- Create a reusable Modal component to display forms for adding and editing contacts.
- Ensure the Modal component receives props for the title, children elements, and a function to close the modal.
- Create an AddContact component with form fields for entering contact name and phone number.
- Implement a submit handler to pass the new contact data to the parent component.
- Use the Modal component to wrap the AddContact form.
- Create a ContactList component to display the list of contacts.
- Add buttons for editing and deleting each contact.
- Update an App component to manage the state of the contacts list.
- Implement state management to handle adding, updating, and deleting contacts.
- Use state variables to control the visibility of AddContact and EditContact modals.
Prerequisites:
Steps to create the React application and installing module:
Step 1: Create a React application using the following command:
npx create-react-app myapp
Step 2: After creating your project folder i.e. foldername, move to it using the following command:
cd myapp
Step 3: After creating the ReactJS application, Install the material-ui modules using the following command:
npm install bootstrap
Project structure:
The updated dependencies in package.json file will look like:
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"bootstrap": "^5.3.3",
"react": "^18.2.0",
"react-router-dom": "^6.25.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}
Example: Now write down the following codes in respective files.
App.js
// src/App.js
import React, { useState } from 'react';
import ContactList from './ContactList';
import AddContact from './AddContact';
import EditContact from './EditContact';
import { v4 as uuidv4 } from 'uuid';
const App = () => {
const [contacts, setContacts] = useState([]);
const [editContact, setEditContact] = useState(null);
const [showAddModal, setShowAddModal] = useState(false);
const [showEditModal, setShowEditModal] = useState(false);
const addContact = (contact) => {
setContacts([...contacts, { ...contact, id: uuidv4() }]);
setShowAddModal(false);
};
const deleteContact = (id) => {
setContacts(contacts.filter(contact => contact.id !== id));
};
const updateContact = (updatedContact) => {
setContacts(contacts.map(contact => (contact.id === updatedContact.id ? updatedContact : contact)));
setShowEditModal(false);
};
const handleEdit = (contact) => {
setEditContact(contact);
setShowEditModal(true);
};
return (
<div className="container mt-5">
<h1 className="text-center">Contacts Manager</h1>
<button className="btn btn-primary my-3" onClick={() => setShowAddModal(true)}>Add Contact</button>
<ContactList contacts={contacts} onDelete={deleteContact} onEdit={handleEdit} />
{showAddModal && <AddContact onAdd={addContact} onClose={() => setShowAddModal(false)} />}
{showEditModal && <EditContact contact={editContact} onUpdate={updateContact} onClose={() => setShowEditModal(false)} />}
</div>
);
};
export default App;
AddContact.js
// src/AddContact.js
import React, { useState } from 'react';
import Modal from './Modal';
const AddContact = ({ onAdd, onClose }) => {
const [name, setName] = useState('');
const [phone, setPhone] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
onAdd({ name, phone });
setName('');
setPhone('');
onClose();
};
return (
<Modal title="Add Contact" onClose={onClose}>
<form onSubmit={handleSubmit}>
<div className="mb-3">
<label className="form-label">Name</label>
<input
type="text"
className="form-control"
placeholder="Name"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
</div>
<div className="mb-3">
<label className="form-label">Phone Number</label>
<input
type="tel"
className="form-control"
placeholder="Phone Number"
value={phone}
onChange={(e) => setPhone(e.target.value)}
required
/>
</div>
<button type="submit" className="btn btn-primary">
<i className="fas fa-plus"></i> Add
</button>
</form>
</Modal>
);
};
export default AddContact;
EditContact.js
// src/EditContact.js
import React, { useState, useEffect } from 'react';
import Modal from './Modal';
const EditContact = ({ contact, onUpdate, onClose }) => {
const [name, setName] = useState(contact.name);
const [phone, setPhone] = useState(contact.phone);
useEffect(() => {
setName(contact.name);
setPhone(contact.phone);
}, [contact]);
const handleSubmit = (e) => {
e.preventDefault();
onUpdate({ ...contact, name, phone });
onClose();
};
return (
<Modal title="Edit Contact" onClose={onClose}>
<form onSubmit={handleSubmit}>
<div className="mb-3">
<label className="form-label">Name</label>
<input
type="text"
className="form-control"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
</div>
<div className="mb-3">
<label className="form-label">Phone Number</label>
<input
type="tel"
className="form-control"
value={phone}
onChange={(e) => setPhone(e.target.value)}
required
/>
</div>
<button type="submit" className="btn btn-success me-2">
<i className="fas fa-save"></i> Update
</button>
<button type="button" className="btn btn-secondary" onClick={onClose}>
Cancel
</button>
</form>
</Modal>
);
};
export default EditContact;
ContactList.js
// src/ContactList.js
import React from 'react';
const ContactList = ({ contacts, onDelete, onEdit }) => {
return (
<div className="container mt-4">
<h2 className="text-center">Contact List</h2>
<ul className="list-group">
{contacts.map((contact) => (
<li key={contact.id} className="list-group-item d-flex justify-content-between align-items-center">
<div>
<i className="fas fa-user me-2"></i>
<strong>{contact.name}</strong>
<div className="text-muted">
<i className="fas fa-phone-alt me-2"></i>
{contact.phone}
</div>
</div>
<div>
<button className="btn btn-warning btn-sm me-2" onClick={() => onEdit(contact)}>
<i className="fas fa-edit"></i>
</button>
<button className="btn btn-danger btn-sm" onClick={() => onDelete(contact.id)}>
<i className="fas fa-trash-alt"></i>
</button>
</div>
</li>
))}
</ul>
</div>
);
};
export default ContactList;
Modal.js
// src/Modal.js
import React from 'react';
const Modal = ({ title, children, onClose }) => {
return (
<div className="modal fade show d-block" tabIndex="-1" role="dialog">
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">{title}</h5>
<button type="button" className="close" aria-label="Close" onClick={onClose}>
<span aria-hidden="true">×</span>
</button>
</div>
<div className="modal-body">
{children}
</div>
</div>
</div>
</div>
);
};
export default Modal;
Step to run application: Run the application using the following command from the root directory of the project.
npm start
Output: Now open your browser and go to http://localhost:3000
Contact List