In this tutorial we will create CRUD app but this time with the help of ContextAPi or useContext, useReducer.
To create a fully functional React CRUD app using useReducer in combination with useContext, we will follow these steps. This approach will help manage the global state of employees more efficiently.
Step 1: Setting Up the React Project
First, create a new React app:
npx create-react-app react-crud-app
cd react-crud-app
npm install axios react-router-dom@6
Step 2: Setting Up JSON Server
Create a db.json file in the root of your project:
{
"employees": [
{ "id": 1, "firstName": "Ramesh", "lastName": "Fadatare", "email": "ram@gmail.com" },
{ "id": 2, "firstName": "John", "lastName": "Cena", "email": "john@gmail.com" },
{ "id": 3, "firstName": "Tom", "lastName": "Cruise", "email": "tom@gmail.com" },
{ "id": 4, "firstName": "Admin", "lastName": "admin", "email": "admin@gmail.com" }
]
}
Install and run json-server:
npm install -g json-server
json-server --watch db.json --port 5000
Step 3: Creating Context and Reducer
Create the EmployeeContext and employeeReducer to manage the global state of employees.
src/context/EmployeeContext.js:
//React is imported to use its functionalities.
//createContext, useReducer, and useEffect are hooks from React.
//axios is a promise-based HTTP client used for making requests to a server.
import React, { createContext, useReducer, useEffect } from 'react';
import axios from 'axios';
// Create the EmployeeContext
//EmployeeContext is created using createContext which allows sharing state across components without passing props manually at every level.
export const EmployeeContext = createContext();
// Define the initial state
const initialState = {
employees: []
};
// Define the reducer function
const employeeReducer = (state, action) => {
switch (action.type) {
case 'SET_EMPLOYEES':
return { ...state, employees: action.payload };
case 'ADD_EMPLOYEE':
return { ...state, employees: [...state.employees, action.payload] };
case 'UPDATE_EMPLOYEE':
return {
...state,
employees: state.employees.map(emp => emp.id === action.payload.id ? action.payload : emp)
};
case 'DELETE_EMPLOYEE':
return {
...state,
employees: state.employees.filter(emp => emp.id !== action.payload)
};
default:
return state;
}
};
// Create the EmployeeProvider component
const EmployeeProvider = ({ children }) => {
const [state, dispatch] = useReducer(employeeReducer, initialState);
// Fetch employees from server when component mounts
useEffect(() => {
axios.get('http://localhost:5000/employees')
.then(response => {
dispatch({ type: 'SET_EMPLOYEES', payload: response.data });
})
.catch(error => console.log(error));
}, []);
return (
<EmployeeContext.Provider value={{ state, dispatch }}>
{children}
</EmployeeContext.Provider>
);
};
export default EmployeeProvider;
Explanation
Imports:
Reactis imported to use its functionalities.createContext,useReducer, anduseEffectare hooks from React.axiosis a promise-based HTTP client used for making requests to a server.
Creating Context:
EmployeeContextis created usingcreateContextwhich allows sharing state across components without passing props manually at every level.
Initial State:
- The
initialStateis defined with anemployeesarray to hold employee data.
- The
Reducer Function:
- The
employeeReducerfunction updates the state based on the action type.SET_EMPLOYEES: Sets the entire employee list.ADD_EMPLOYEE: Adds a new employee to the list.UPDATE_EMPLOYEE: Updates an existing employee’s details.DELETE_EMPLOYEE: Removes an employee from the list based on their ID.
- The
stateis updated immutably using spread operators (...).
Provider Component:
EmployeeProvideris a component that provides state and dispatch functions to its children.useReducerhook is used to manage the state based on theemployeeReducerfunction andinitialState.useEffecthook is used to fetch employees from the server when the component mounts ([]ensures it runs only once).axios.getfetches data from the server. On success, the employee data is dispatched to the state usingSET_EMPLOYEESaction.- The
EmployeeContext.Providerwraps the children components, providing them access tostateanddispatch.
Step 4: Creating Components
Create the necessary component files and use the context to manage state.
src/components/EmployeeList.js:
import React, { useContext } from 'react';
import { EmployeeContext } from '../context/EmployeeContext';
import { Link } from 'react-router-dom';
const EmployeeList = () => {
const { state } = useContext(EmployeeContext); // Access state from context
return (
<div className="employee-list">
<h2>Employees List</h2>
<Link to="/add" className="btn btn-primary">Add Employee</Link>
<table className="table">
<thead>
<tr>
<th>Employee First Name</th>
<th>Employee Last Name</th>
<th>Employee Email Id</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{state.employees.map(employee => (
<tr key={employee.id}>
<td>{employee.firstName}</td>
<td>{employee.lastName}</td>
<td>{employee.email}</td>
<td>
<Link to={`/update/${employee.id}`} className="btn btn-info">Update</Link>
<Link to={`/delete/${employee.id}`} className="btn btn-danger">Delete</Link>
<Link to={`/view/${employee.id}`} className="btn btn-success">View</Link>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default EmployeeList;
Explanation
This EmployeeList component in React uses the EmployeeContext to display a list of employees, providing options to add, update, delete, and view details for each employee. Here’s a detailed explanation:
Imports:
useContextis imported from React to access the context.EmployeeContextis imported from the context file to access the employee state.Linkis imported fromreact-router-domfor navigation between routes.
Component Definition:
EmployeeListis a functional component.useContext(EmployeeContext)is used to get the current state fromEmployeeContext. This gives access to thestateobject, which contains the list of employees.
Component Return:
- The component returns a JSX structure that includes:
- A heading
Employees List. - A
Linkcomponent for adding a new employee, which navigates to the/addroute. - A table to display the list of employees.
- The table header includes columns for the first name, last name, email ID, and actions.
- The table body maps over the
state.employeesarray to create a row for each employee.- Each row includes cells for the employee’s first name, last name, and email.
- The actions cell contains
Linkcomponents for updating, deleting, and viewing the employee, navigating to the respective routes (/update,/delete,/view) with the employee’s ID as a parameter.
- Each
Linkis styled with Bootstrap classes for buttons (btn,btn-primary,btn-info,btn-danger,btn-success).
- A heading
Export Component:
- The
EmployeeListcomponent is exported as the default export, making it available for import in other parts of the application.
src/components/AddEmployee.js:
import React, { useState, useContext } from 'react';
import axios from 'axios';
import { useNavigate } from 'react-router-dom';
import { EmployeeContext } from '../context/EmployeeContext';
const AddEmployee = () => {
const [employee, setEmployee] = useState({ firstName: '', lastName: '', email: '' });
const { dispatch } = useContext(EmployeeContext); // Access dispatch from context
const navigate = useNavigate();
const handleChange = (e) => {
const { name, value } = e.target;
setEmployee({ ...employee, [name]: value });
};
const handleSubmit = (e) => {
e.preventDefault();
axios.post('http://localhost:5000/employees', employee)
.then(response => {
dispatch({ type: 'ADD_EMPLOYEE', payload: response.data }); // Dispatch add employee action
navigate('/');
})
.catch(error => console.log(error));
};
return (
<div className="add-employee">
<h2>Add Employee</h2>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label>First Name</label>
<input type="text" name="firstName" value={employee.firstName} onChange={handleChange} required />
</div>
<div className="form-group">
<label>Last Name</label>
<input type="text" name="lastName" value={employee.lastName} onChange={handleChange} required />
</div>
<div className="form-group">
<label>Email</label>
<input type="email" name="email" value={employee.email} onChange={handleChange} required />
</div>
<button type="submit" className="btn btn-primary">Add</button>
</form>
</div>
);
};
export default AddEmployee;
Explanation
The AddEmployee component in React allows users to add a new employee to the list. It uses state to manage form input, context to dispatch actions, and axios to handle HTTP requests. Here’s a detailed breakdown of the code:
Imports:
useStateanduseContexthooks from React for state management and accessing context.axiosfor making HTTP requests.useNavigatefromreact-router-domfor programmatic navigation.EmployeeContextfor accessing the employee context.
Component Definition and State Initialization:
AddEmployeeis a functional component.employeestate is initialized with an object containingfirstName,lastName, andemail.dispatchis obtained fromEmployeeContextto dispatch actions.navigateis used to navigate to different routes programmatically.
Handle Change Function:
handleChangeupdates theemployeestate based on the input field changes.- It uses the event object to get the
nameandvalueof the changed input, and updates the corresponding property in theemployeestate.
Handle Submit Function:
handleSubmithandles the form submission.- It prevents the default form submission behavior.
axios.postsends a POST request to the server to add the new employee.- On success, it dispatches the
ADD_EMPLOYEEaction with the new employee data and navigates back to the home page (/). - Any errors are logged to the console.
Component Return:
- The component renders a form for adding a new employee.
- The form includes three input fields for
firstName,lastName, andemail, each bound to the corresponding state properties and usinghandleChangeto update the state. - The form submission is handled by
handleSubmit. - A submit button with the class
btn btn-primaryto style it using Bootstrap.
Export Component:
- The
AddEmployeecomponent is exported as the default export, making it available for import in other parts of the application.
Summary
- The
AddEmployeecomponent provides a form for adding a new employee, managing form input with local state. - It dispatches an action to update the global state using the
EmployeeContext. - It uses
axiosto send a POST request to add the employee to the server. - On successful addition, it navigates back to the home page.
src/components/UpdateEmployee.js:
import React, { useState, useEffect, useContext } from 'react';
import axios from 'axios';
import { useParams, useNavigate } from 'react-router-dom';
import { EmployeeContext } from '../context/EmployeeContext';
const UpdateEmployee = () => {
const { id } = useParams();
const [employee, setEmployee] = useState({ firstName: '', lastName: '', email: '' });
const { state, dispatch } = useContext(EmployeeContext); // Access state and dispatch from context
const navigate = useNavigate();
useEffect(() => {
const currentEmployee = state.employees.find(emp => emp.id === parseInt(id));
if (currentEmployee) {
setEmployee(currentEmployee); // Set the current employee data
}
}, [id, state.employees]);
const handleChange = (e) => {
const { name, value } = e.target;
setEmployee({ ...employee, [name]: value });
};
const handleSubmit = (e) => {
e.preventDefault();
axios.put(`http://localhost:5000/employees/${id}`, employee)
.then(response => {
dispatch({ type: 'UPDATE_EMPLOYEE', payload: response.data }); // Dispatch update employee action
navigate('/');
})
.catch(error => console.log(error));
};
return (
<div className="update-employee">
<h2>Update Employee</h2>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label>First Name</label>
<input type="text" name="firstName" value={employee.firstName} onChange={handleChange} required />
</div>
<div className="form-group">
<label>Last Name</label>
<input type="text" name="lastName" value={employee.lastName} onChange={handleChange} required />
</div>
<div className="form-group">
<label>Email</label>
<input type="email" name="email" value={employee.email} onChange={handleChange} required />
</div>
<button type="submit" className="btn btn-primary">Update</button>
</form>
</div>
);
};
export default UpdateEmployee;
Explanation
The UpdateEmployee component is designed to allow users to update an existing employee’s information. This component effectively leverages React’s hooks for state management and side effects, as well as context for global state management. Below is an extensive breakdown of the code and its workings:
Imports:
useState,useEffect, anduseContextare imported from React to handle state, side effects, and context, respectively.axiosis used for making HTTP requests.useParamsretrieves the dynamicidparameter from the URL.useNavigatefacilitates programmatic navigation.EmployeeContextis imported to access the global state and dispatch actions.
Component Definition and State Initialization:
UpdateEmployeeis defined as a functional component.useParamsextracts theidparameter from the URL, which is used to identify the employee to be updated.employeestate is initialized to hold the employee details.stateanddispatchare destructured fromEmployeeContextto access the list of employees and to dispatch actions.useNavigateis set up for navigation.
Fetching Current Employee Data:
useEffectis employed to fetch the current employee data when the component mounts or whenidorstate.employeeschanges.- It uses
findto locate the employee in the state based on theidparameter, then sets this employee’s data into the local state usingsetEmployee.
Handling Input Changes:
handleChangefunction updates the local state as the user modifies the input fields.- It dynamically updates the
employeestate based on the input field’snameattribute and its value.
Submitting the Form:
handleSubmitmanages the form submission.- It prevents the default form behavior, sends a PUT request to update the employee data on the server, and upon success, dispatches the
UPDATE_EMPLOYEEaction to update the global state. - It navigates back to the home page after the update.
Rendering the Component:
- The component renders a form pre-filled with the current employee’s data.
- The form includes input fields for
firstName,lastName, andemail, each bound to the respective properties in theemployeestate. - The
handleChangefunction ensures that any changes in the input fields are reflected in the state. - The form submission is managed by
handleSubmit, which updates the employee data.
Exporting the Component:
- The
UpdateEmployeecomponent is exported as the default export, making it available for import and use in other parts of the application.
src/components/ViewEmployee.js:
import React, { useState, useEffect, useContext } from 'react';
import axios from 'axios';
import { useParams } from 'react-router-dom';
import { EmployeeContext } from '../context/EmployeeContext';
const ViewEmployee = () => {
const { id } = useParams();
const [employee, setEmployee] = useState({ firstName: '', lastName: '', email: '' });
const { state } = useContext(EmployeeContext); // Access state from context
useEffect(() => {
const currentEmployee = state.employees.find(emp => emp.id === parseInt(id));
if (currentEmployee) {
setEmployee(currentEmployee); // Set the current employee data
} else {
axios.get(`http://localhost:5000/employees/${id}`)
.then(response => {
setEmployee(response.data); // Fetch and set employee data if not found in context
})
.catch(error => console.log(error));
}
}, [id, state.employees]);
return (
<div className="view-employee">
<h2>View Employee</h2>
<p>First Name: {employee.firstName}</p>
<p>Last Name: {employee.lastName}</p>
<p>Email: {employee.email}</p>
</div>
);
};
export default ViewEmployee;
Explanation:
The ViewEmployee component allows users to view details of a specific employee. It uses context to fetch data if available, and falls back to an API call if the data isn’t present in the context. Here’s a detailed explanation:
Imports:
useState,useEffect, anduseContextfrom React to handle state, side effects, and context, respectively.axiosfor making HTTP requests.useParamsfromreact-router-domto extract the dynamicidparameter from the URL.EmployeeContextfor accessing the global state.
Component Definition and State Initialization:
ViewEmployeeis defined as a functional component.useParamsextracts theidparameter from the URL.employeestate is initialized to hold the employee details.stateis destructured fromEmployeeContextto access the list of employees.
Fetching Employee Data:
useEffectruns when the component mounts or whenidorstate.employeeschanges.- It first attempts to find the employee in the context’s state using
find. - If the employee is found, it sets the
employeestate with the found employee data. - If the employee is not found, it makes an HTTP GET request using
axiosto fetch the employee data from the server. - The fetched data is then set in the
employeestate.
Rendering the Component:
- The component renders a simple view displaying the employee’s
firstName,lastName, andemail.
Exporting the Component:
- The
ViewEmployeecomponent is exported as the default export, making it available for import in other parts of the application.
- The
ViewEmployeecomponent is designed to display details of a specific employee. - It first tries to fetch the employee data from the context. If not found, it makes an API call to get the data.
- This approach ensures that if the employee data is already available in the context, it doesn’t make unnecessary API calls, thus optimizing performance.
- The component uses React hooks (
useState,useEffect, anduseContext) for managing state and side effects effectively.
src/components/DeleteEmployee.js:
import React, { useEffect, useContext } from 'react';
import axios from 'axios';
import { useParams, useNavigate } from 'react-router-dom';
import { EmployeeContext } from '../context/EmployeeContext';
const DeleteEmployee = () => {
const { id } = useParams();
const { dispatch } = useContext(EmployeeContext); // Access dispatch from context
const navigate = useNavigate();
useEffect(() => {
axios.delete(`http://localhost:5000/employees/${id}`)
.then(response => {
dispatch({ type: 'DELETE_EMPLOYEE', payload: parseInt(id) }); // Dispatch delete employee action
navigate('/');
})
.catch(error => console.log(error));
}, [id, navigate, dispatch]);
return (
<div className="delete-employee">
<h2>Deleting Employee...</h2>
</div>
);
};
export default DeleteEmployee;
Explanation:
The DeleteEmployee component is responsible for deleting an employee based on their ID. Upon mounting, it triggers an API call to delete the employee from the backend and updates the global state accordingly. Here’s a breakdown of the code:
Imports:
useEffectanduseContextfrom React to handle side effects and context, respectively.axiosfor making HTTP requests.useParamsto get theidparameter from the URL.useNavigateto navigate programmatically.EmployeeContextto access the dispatch function for the global state.
Component Definition and Deletion Logic:
DeleteEmployeeis a functional component.useParamsis used to extract theidparameter from the URL.dispatchis obtained fromEmployeeContextto dispatch actions.navigateis used for programmatic navigation.
UseEffect Hook for Deletion:
useEffectruns when the component mounts.axios.deletesends a DELETE request to the server to delete the employee with the specifiedid.- Upon successful deletion, the
DELETE_EMPLOYEEaction is dispatched to update the global state. navigateredirects the user to the home page (/).- Dependencies
[id, navigate, dispatch]ensure the effect runs when these values change.
Rendering the Component:
- The component renders a message indicating that the employee is being deleted.
Exporting the Component:
- The
DeleteEmployeecomponent is exported as the default export, making it available for import in other parts of the application.
- The
DeleteEmployeecomponent handles the deletion of an employee. - It uses the
useEffecthook to perform the delete operation when the component mounts. - The component accesses the
idparameter from the URL to identify which employee to delete. - It uses
axiosto make an HTTP DELETE request to the backend. - Upon successful deletion, it dispatches a
DELETE_EMPLOYEEaction to update the global state and navigates back to the home page. - The component displays a simple message indicating the deletion process.
src/components/Navbar.js:
import React from 'react';
import { Link } from 'react-router-dom';
const Navbar = () => {
return (
<nav className="navbar">
<h1>Employee Management App</h1>
<div className="links">
<Link to="/">Home</Link>
<Link to="/add">Add Employee</Link>
</div>
</nav>
);
};
export default Navbar;
Explanation:
The Navbar component provides navigation links for the application, allowing users to easily navigate to the home page and the add employee page. Here’s a detailed breakdown of the code:
Imports:
Reactis imported to create the functional component.Linkis imported fromreact-router-domto create navigation links that enable client-side routing.
Component Definition:
Navbaris defined as a functional component.- It returns a JSX structure that represents the navigation bar.
JSX Structure:
- The
<nav>element is given a class name ofnavbarfor styling purposes. - Inside the
<nav>element:- An
<h1>element displays the title of the application: “Employee Management App”. - A
<div>with the class namelinkscontains the navigation links.<Link to="/">Home</Link>creates a link to the home page.<Link to="/add">Add Employee</Link>creates a link to the add employee page.
- An
Exporting the Component:
- The
Navbarcomponent is exported as the default export, making it available for import and use in other parts of the application.
- The
Navbarcomponent provides a simple navigation bar for the application. - It uses
Linkfromreact-router-domto create links for client-side navigation. - The navigation bar includes links to the home page and the add employee page, facilitating easy navigation.
- The component is styled using the
navbarandlinksclass names, which can be defined in an external CSS file to apply the desired styles.
Step 5: Creating the Main App Component
Update the main App.js file to use the EmployeeProvider and include the necessary routes.
src/App.js:
import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Navbar from './components/Navbar';
import EmployeeList from './components/EmployeeList';
import AddEmployee from './components/AddEmployee';
import UpdateEmployee from './components/UpdateEmployee';
import ViewEmployee from './components/ViewEmployee';
import DeleteEmployee from './components/DeleteEmployee';
import EmployeeProvider from './context/EmployeeContext';
import './App.css';
function App() {
return (
<EmployeeProvider> {/* Wrap the app in EmployeeProvider */}
<Router>
<div className="App">
<Navbar />
<div className="content">
<Routes>
<Route exact path="/" element={<EmployeeList />} />
<Route path="/add" element={<AddEmployee />} />
<Route path="/update/:id" element={<UpdateEmployee />} />
<Route path="/view/:id" element={<ViewEmployee />} />
<Route path="/delete/:id" element={<DeleteEmployee />} />
</Routes>
</div>
</div>
</Router>
</EmployeeProvider>
);
}
export default App;
Explanation:
The App component sets up the main structure of the application, incorporating routing and context for managing employee data. Here’s an in-depth explanation of the code:
Imports:
Reactfor building the component.BrowserRouter,Route, andRoutesfromreact-router-domfor setting up client-side routing.Navbar,EmployeeList,AddEmployee,UpdateEmployee,ViewEmployee, andDeleteEmployeecomponents for different parts of the application.EmployeeProviderfrom the context file to wrap the application and provide global state management.App.cssfor styling.
App Component Definition:
- The
Appcomponent is defined as a functional component. - The entire application is wrapped in
EmployeeProviderto provide context for managing employee data across the app. Routeris used to enable routing within the app.- Inside the
Router, the structure includes:Navbarcomponent for the navigation bar.- A
divwith a class namecontentthat contains the routing logic usingRoutesandRoute.
Routes Configuration:
- The
Routescomponent contains severalRoutecomponents, each defining a path and the component that should be rendered for that path. exact path="/"renders theEmployeeListcomponent at the root URL.path="/add"renders theAddEmployeecomponent for adding a new employee.path="/update/:id"renders theUpdateEmployeecomponent for updating an employee, where:idis a dynamic parameter.path="/view/:id"renders theViewEmployeecomponent for viewing an employee’s details.path="/delete/:id"renders theDeleteEmployeecomponent for deleting an employee.
Exporting the Component:
- The
Appcomponent is exported as the default export, making it available for import and use in the entry point of the application (e.g.,index.js).
- The
Appcomponent serves as the main entry point for the application. - It uses
EmployeeProviderto wrap the entire app, providing a context for managing employee state. - The routing is set up using
react-router-domto navigate between different views such as listing, adding, updating, viewing, and deleting employees. - The
Navbarcomponent is included to provide easy navigation between different parts of the application.
Step 6: Styling the App
Ensure the CSS in App.css matches the design provided in the image.
src/App.css:
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.navbar {
background-color: #333;
color: #fff;
padding: 10px 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.navbar h1 {
margin: 0;
}
.navbar .links a {
color: #fff;
margin-left: 20px;
text-decoration: none;
}
.btn {
padding: 5px 10px;
margin: 0 5px;
border: none;
color: #fff;
cursor: pointer;
}
.btn-primary {
background-color: #007bff;
}
.btn-info {
background-color: #17a2b8;
}
.btn-danger {
background-color: #dc3545;
}
.btn-success {
background-color: #28a745;
}
.table {
width: 100%;
margin: 20px 0;
border-collapse: collapse;
}
.table th, .table td {
padding: 10px;
border: 1px solid #ddd;
text-align: left;
}
.table th {
background-color: #f8f8f8;
}
.form-group {
margin: 10px 0;
}
.form-group label {
display: block;
margin-bottom: 5px;
}
.form-group input {
width: 100%;
padding: 8px;
box-sizing: border-box;
}
The provided CSS styles are designed to create a clean and functional user interface for the Employee Management App. Here’s a detailed explanation of the CSS rules:
Global Styles:
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
- Sets the global font to Arial or a sans-serif fallback.
- Applies a light gray background color to the entire body.
- Removes default margin and padding for the body.
Navbar Styles:
.navbar {
background-color: #333;
color: #fff;
padding: 10px 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.navbar h1 {
margin: 0;
}
.navbar .links a {
color: #fff;
margin-left: 20px;
text-decoration: none;
}
.navbar: Styles the navigation bar with a dark background, white text, padding, and flexbox layout for alignment and spacing..navbar h1: Ensures no margin around the header inside the navbar..navbar .links a: Styles the links inside the navbar to be white, without underlines, and with left margin for spacing.
Button Styles:
.btn {
padding: 5px 10px;
margin: 0 5px;
border: none;
color: #fff;
cursor: pointer;
}
.btn-primary {
background-color: #007bff;
}
.btn-info {
background-color: #17a2b8;
}
.btn-danger {
background-color: #dc3545;
}
.btn-success {
background-color: #28a745;
}
.btn: A base class for buttons that sets padding, margin, border removal, white text color, and pointer cursor..btn-primary,.btn-info,.btn-danger,.btn-success: Specific button classes that apply different background colors for different types of actions.
Table Styles:
.table {
width: 100%;
margin: 20px 0;
border-collapse: collapse;
}
.table th, .table td {
padding: 10px;
border: 1px solid #ddd;
text-align: left;
}
.table th {
background-color: #f8f8f8;
}
.table: Styles tables to take full width, adds margin, and collapses borders..table th, .table td: Adds padding, borders, and left text alignment to table headers and cells..table th: Sets a light background color for table headers.
Form Group Styles:
.form-group {
margin: 10px 0;
}
.form-group label {
display: block;
margin-bottom: 5px;
}
.form-group input {
width: 100%;
padding: 8px;
box-sizing: border-box;
}
.form-group: Adds margin around form groups..form-group label: Ensures labels are block-level elements with bottom margin for spacing..form-group input: Styles inputs to take full width, adds padding, and ensures padding and borders are included in the element’s total width and height usingbox-sizing: border-box.
Summary
- The CSS styles provide a clean, functional, and responsive design for the Employee Management App.
- The use of flexbox for the navbar ensures proper alignment and spacing of elements.
- Consistent button styling is achieved with base and modifier classes.
- Table and form styles are designed for readability and usability.
Welcome to DevTechTutor.com, your ultimate resource for mastering web development and technology! Whether you're a beginner eager to dive into coding or an experienced developer looking to sharpen your skills, DevTechTutor.com is here to guide you every step of the way. Our mission is to make learning web development accessible, engaging, and effective.