Approach to create Frontend
- Create Components for `Appointments`, `Doctors`, `Patients`, `AppointmentCard`, `DoctorCard`, and `PatientCard` within `src/components`
- Create a main `App` component that utilizes React Router for navigation.
- Design styles for each component to enhance the visual appeal.
Example: Below is the code for the all the above files named above:
Javascript
//App.js import React from 'react' ; import { BrowserRouter as Router, Routes, Route, Link, useNavigate } from 'react-router-dom' ; import Appointments from './components/Appointments' ; import Doctors from './components/Doctors' ; import Patients from './components/Patients' ; import './App.css' const App = () => { const isLinkActive = (path) => window.location.pathname === path; return ( <Router> <div className= "container" > <h1 style={{ color: "green" }}> GFG- Hospital Managment App </h1> <nav> <ul> <li className={ isLinkActive( '/appointments' ) ? 'active' : '' }> <Link to= "/appointments" > Appointments </Link> </li> <li className={ isLinkActive( '/doctors' ) ? 'active' : '' }> <Link to= "/doctors" > Doctors </Link> </li> <li className={ isLinkActive( '/patients' ) ? 'active' : '' }> <Link to= "/patients" > Patients </Link> </li> </ul> </nav> <Routes> <Route path= "/appointments" element={<Appointments />} /> <Route path= "/" element={<Appointments />} /> <Route path= "/doctors" element={<Doctors />} /> <Route path= "/patients" element={<Patients />} /> </Routes> </div> </Router> ); } export default App; |
Javascript
//Appointments.js import React, { useState, useEffect } from 'react' ; import axios from 'axios' ; import AppointmentCard from './AppointmentCard' ; import './Appointment.css' const Appointments = () => { const [appointments, setAppointments] = useState([]); const [newAppointment, setNewAppointment] = useState( { patientName: '' , doctorName: '' , date: '' }); const [selectedAppointment, setSelectedAppointment] = useState( null ); const [isEditMode, setIsEditMode] = useState( false ); useEffect(() => { axios .get( 'http://localhost:5000/appointments' ) .then( response => setAppointments(response.data)) . catch ( error => console.error( 'Error fetching appointments:' , error) ); }, []); const handleAddAppointment = (e) => { e.preventDefault(); axios .post( 'http://localhost:5000/appointments/add' , newAppointment) .then(response => { console.log(response.data); setAppointments( [ ...appointments, response.data]); setNewAppointment( { patientName: '' , doctorName: '' , date: '' }); }) . catch (error => console.error( 'Error adding appointment:' , error)); }; const handleUpdateAppointment = (id, e) => { e.preventDefault(); axios .post( `http: //localhost:5000/appointments/update/${id}`, selectedAppointment) .then(response => { console.log(response.data); const updateApp = { ...selectedAppointment, _id: id }; setAppointments( appointments.map( appointment => (appointment._id === id ? updateApp : appointment) )); setSelectedAppointment( null ); setIsEditMode( false ); // Switch back to Add mode }) . catch ( error => console.error( 'Error updating appointment:' , error)); }; const handleDeleteAppointment = (id) => { axios . delete ( `http: //localhost:5000/appointments/delete/${id}`) .then(response => { console.log(response.data); setAppointments( appointments.filter( appointment => appointment._id !== id) ); }) . catch (error => console.error( 'Error deleting appointment:' , error)); }; const handleEditAppointment = (appointment) => { setSelectedAppointment(appointment); setIsEditMode( true ); // Switch to Edit mode }; return ( <div className= 'flex-row' style={{ width: "100%" }}> <div className= 'flex-column' > <div className= 'add-form' > <h4> { isEditMode ? 'Edit Appointment' : 'Add New Appointment' } </h4> <form className= "appointment-form" onSubmit={ isEditMode ? (e) => handleUpdateAppointment(selectedAppointment._id, e) : handleAddAppointment }> <label>Patient Name:</label> <input type= "text" value={ isEditMode ? selectedAppointment.patientName : newAppointment.patientName } onChange={ (e) => isEditMode ? setSelectedAppointment( { ...selectedAppointment, patientName: e.target.value }) : setNewAppointment( { ...newAppointment, patientName: e.target.value })} /> <label>Doctor Name:</label> <input type= "text" value={ isEditMode ? selectedAppointment.doctorName : newAppointment.doctorName } onChange={ (e) => isEditMode ? setSelectedAppointment( { ...selectedAppointment, doctorName: e.target.value }) : setNewAppointment( { ...newAppointment, doctorName: e.target.value })} /> <label>Date:</label> <input type= "date" value={ isEditMode ? selectedAppointment.date : newAppointment.date } onChange={ (e) => isEditMode ? setSelectedAppointment( { ...selectedAppointment, date: e.target.value }) : setNewAppointment( { ...newAppointment, date: e.target.value })} /> <button type= "submit" > { isEditMode ? 'Update Appointment' : 'Add Appointment' } </button> </form> </div> </div> <div className= 'appointments' > <h3>Appointments ( { appointments.length }) </h3> <div className= "appointment-list" > {appointments.map(appointment => ( <AppointmentCard key={appointment._id} appointment={appointment} onEdit={handleEditAppointment} onDelete={handleDeleteAppointment} /> ))} </div> </div> </div> ); }; export default Appointments; |
Javascript
// src/components/AppointmentCard.js import React from 'react' ; const AppointmentCard = ( { appointment, onEdit, onDelete } ) => { return ( <div className= "appointment-card" > <p> <span> Patient: </span> {appointment.patientName} </p> <p> <span> Doctor: </span> {appointment.doctorName}</p> <p> <span> Date: </span> { new Date(appointment.date) .toLocaleDateString() } </p> <div className= 'btn-container' > <button onClick={ () => onEdit(appointment) }> Edit </button> <button onClick={ () => onDelete(appointment._id) }> Delete </button> </div> </div> ); }; export default AppointmentCard; |
Javascript
//Doctors.js import React, { useState, useEffect } from 'react' ; import axios from 'axios' ; import DoctorCard from './DoctorCard' ; import './Doctors.css' const Doctors = () => { const [doctors, setDoctors] = useState([]); const [newDoctor, setNewDoctor] = useState( { name: '' , specialty: '' }); const [selectedDoctor, setSelectedDoctor] = useState( null ); const [isEditMode, setIsEditMode] = useState( false ); useEffect( () => { axios .get( 'http://localhost:5000/doctors' ) .then( response => setDoctors(response.data)) . catch ( error => console.error( 'Error fetching doctors:' , error) ); }, []); const handleAddDoctor = (e) => { e.preventDefault(); axios .post( 'http://localhost:5000/doctors/add' , newDoctor) .then( response => { console.log( "doc" , response.data); setDoctors( [ ...doctors, response.data ] ); setNewDoctor( { name: '' , specialty: '' }); }) . catch ( error => console.error( 'Error adding doctor:' , error)); }; const handleUpdateDoctor = (id, e) => { e.preventDefault(); axios .post( `http: //localhost:5000/doctors/update/${id}`, selectedDoctor) .then(response => { const updateDoc = { ...selectedDoctor, _id: id }; console.log( 'update doc' , updateDoc); setDoctors( doctors.map( doctor => (doctor._id === id ? updateDoc : doctor))); setSelectedDoctor( null ); setIsEditMode( false ); // Switch back to Add mode }) . catch ( error => console.error( 'Error updating doctor:' , error)); }; const handleDeleteDoctor = (id) => { axios. delete ( `http: //localhost:5000/doctors/delete/${id}`) .then(response => { console.log(response.data); setDoctors( doctors .filter(doctor => doctor._id !== id) ); }) . catch ( error => console.error( 'Error deleting doctor:' , error)); }; const handleEditDoctor = (doctor) => { setSelectedDoctor(doctor); setIsEditMode( true ); // Switch to Edit mode }; return ( <div className= 'main-doc-container ' > <div className= 'form-sections ' > <h4> { isEditMode ? 'Edit Doctor' : 'Add New Doctor' } </h4> <form onSubmit={ isEditMode ? (e) => handleUpdateDoctor(selectedDoctor._id, e) : handleAddDoctor}> <label>Name: </label> <input type= "text" value={ isEditMode ? selectedDoctor.name : newDoctor.name } onChange={ (e) => isEditMode ? setSelectedDoctor( { ...selectedDoctor, name: e.target.value }) : setNewDoctor( { ...newDoctor, name: e.target.value })} /> <br /> <label>Specialty: </label> <input type= "text" value= { isEditMode ? selectedDoctor.specialty : newDoctor.specialty } onChange={ (e) => isEditMode ? setSelectedDoctor( { ...selectedDoctor, specialty: e.target.value } ) : setNewDoctor( { ...newDoctor, specialty: e.target.value } )} /> <br /> <button type= "submit" > { isEditMode ? 'Update Doctor' : 'Add Doctor' }</button> </form> </div> <div className= 'doctors-section ' > <h3>Doctors({doctors.length}) </h3> <div className= "doctor-list" > {doctors.map(doctor => ( <DoctorCard key={doctor._id} doctor={doctor} onEdit={handleEditDoctor} onDelete={handleDeleteDoctor} /> ))} </div> </div> </div> ); }; export default Doctors; |
Javascript
// src/components/DoctorCard.js import React from 'react' ; const DoctorCard = ( { doctor, onEdit, onDelete } ) => { return ( <div className= "doctor-card" > <p> {doctor.name} - {doctor.specialty} </p> <div className= 'btn-container' > <button onClick={ () => onEdit(doctor) }> Edit </button> <button onClick={ () => onDelete(doctor._id) }> Delete </button> </div> </div> ); }; export default DoctorCard; |
Javascript
// src/components/Patients.js import React, { useState, useEffect } from 'react' ; import axios from 'axios' ; import './Patients.css' ; import PatientCard from './PatientCard' ; const Patients = () => { const [patients, setPatients] = useState([]); const [newPatient, setNewPatient] = useState({ name: '' , age: '' , gender: '' }); const [selectedPatient, setSelectedPatient] = useState( null ); const [isEditMode, setIsEditMode] = useState( false ); useEffect( () => { axios.get( 'http://localhost:5000/patients' ) .then(response => setPatients(response.data)) . catch (error => console.error( 'Error fetching patients:' , error)); }, []); const handleAddPatient = (e) => { e.preventDefault(); axios.post( 'http://localhost:5000/patients/add' , newPatient) .then(response => { console.log(response.data); setPatients([...patients, response.data]); setNewPatient({ name: '' , age: '' , gender: '' }); }) . catch (error => console.error( 'Error adding patient:' , error)); }; const handleUpdatePatient = (id, e) => { e.preventDefault(); axios.post( `http: //localhost:5000/patients/update/${id}`, selectedPatient) .then(response => { const updatePat = { ...selectedPatient, _id: id }; console.log( 'update patient' , updatePat); setPatients( patients.map( patient => (patient._id === id ? updatePat : patient))); setSelectedPatient( null ); setIsEditMode( false ); // Switch back to Add mode }) . catch ( error => console.error( 'Error updating patient:' , error)); }; const handleDeletePatient = (id) => { axios. delete ( `http: //localhost:5000/patients/delete/${id}`) .then(response => { console.log(response.data); setSelectedPatient( null ); setPatients( patients.filter( patient => patient._id !== id)); }) . catch ( error => console.error( 'Error deleting patient:' , error)); }; const handleEditPatient = (patient) => { setSelectedPatient(patient); setIsEditMode( true ); // Switch to Edit mode }; return ( <div className= 'patient-main ' > <div className= 'form-sections ' > <h4> { isEditMode ? 'Edit Patient' : 'Add New Patient' } </h4> <form onSubmit= { isEditMode ? (e) => handleUpdatePatient(selectedPatient._id, e) : handleAddPatient}> <label>Name: </label> <input type= "text" value={ isEditMode ? selectedPatient.name : newPatient.name } onChange={ (e) => isEditMode ? setSelectedPatient( { ...selectedPatient, name: e.target.value }) : setNewPatient( { ...newPatient, name: e.target.value } )} /> <br /> <label>Age: </label> <input type= "text" value= { isEditMode ? selectedPatient.age : newPatient.age } onChange={ (e) => isEditMode ? setSelectedPatient( { ...selectedPatient, age: e.target.value }) : setNewPatient( { ...newPatient, age: e.target.value } )} /> <br /> <label>Gender: </label> <input type= "text" value= { isEditMode ? selectedPatient.gender : newPatient.gender } onChange={ (e) => isEditMode ? setSelectedPatient( { ...selectedPatient, gender: e.target.value }) : setNewPatient( { ...newPatient, gender: e.target.value })} /> <br /> <button type= "submit" > { isEditMode ? 'Update Patient' : 'Add Patient' } </button> </form> </div> <div className= 'patients-section ' > <h3 style={{ textAlign: "center" }}> Patients ({patients.length}) </h3> <div className= "patient-list" > {patients.map(patient => ( <PatientCard key={patient._id} patient={patient} onEdit={handleEditPatient} onDelete={handleDeletePatient} /> ))} </div> </div> </div> ); }; export default Patients; |
Javascript
import React from 'react' ; const PatientCard = ( { patient, onEdit, onDelete } ) => { return ( <div className= "patient-card" > <h4>{patient.name}</h4> <p>Age: {patient.age}</p> <p>Gender: {patient.gender}</p> <div className= 'btn-container' style={{ width: "100%" }}> <button onClick={ () => onEdit(patient)}> Edit </button> <button onClick={ () => onDelete(patient._id) }> Delete </button> </div> </div> ); }; export default PatientCard; |
CSS
/* App.css */ .container { max-width : 90 vw; margin : 0 auto ; padding : 20px 150px ; background-color : #F5EEE6 ; } nav { background-color : #00a7aa ; padding : 10px ; border-radius: 10px ; } ul { list-style : none ; padding : 0 ; margin : 0 ; display : flex; } li { margin-right : 20px ; } a { text-decoration : none ; color : white ; font-weight : bold ; } a:hover { color : #ffd700 ; } .active { color : #ffd700 ; } /* FLEX */ .flex-column { display : flex; flex- direction : column; justify- content : center ; align-items: center ; } .flex-row { display : flex; flex-wrap: wrap; flex- direction : row; justify- content : space-between; align-items: center ; } |
CSS
/* /src/components/App */ /* Appointment card */ .appointment-card { border : 1px solid #ddd ; border-radius: 8px ; width : 300px ; padding : 16px ; margin : 16px 0 ; background-color : #fff ; box-shadow: 0 0 10px rgba( 0 , 0 , 0 , 0.1 ); transition: box-shadow 0.3 s ease; &:hover { box-shadow: 0 0 15px rgba( 0 , 0 , 0 , 0.2 ); } p { font-size : 16px ; margin-bottom : 10px ; } p { span { font-weight : 900 ; } } button { background-color : #007bff ; color : #fff ; border : none ; padding : 8px 16px ; margin-right : 8px ; cursor : pointer ; transition: background-color 0.3 s ease; &:hover { background-color : #002e5f ; } } } /* Add this to a new CSS file, e.g., AppointmentForm.css */ .appointment-form { max-width : 400px ; margin : 0 auto ; padding : 20px ; border : 1px solid #ddd ; border-radius: 8px ; background-color : #fff ; box-shadow: 0 0 10px rgba( 0 , 0 , 0 , 0.1 ); } .appointment-form h 4 { font-size : 24px ; margin-bottom : 20px ; } .appointment-form label { display : block ; margin-bottom : 8px ; } .appointment-form input { width : 100% ; padding : 8px ; margin-bottom : 16px ; border : 1px solid #ddd ; border-radius: 4px ; } .appointment-form button { background-color : #007bff ; color : #fff ; border : none ; padding : 10px 20px ; border-radius: 4px ; cursor : pointer ; transition: background-color 0.3 s ease; &:hover { background-color : #0056b3 ; } } .appointments { display : flex; flex- direction : column; align-items: center ; height : 100 vh; width : 30 vw; } .add-form { display : flex; flex- direction : column; align-items: center ; margin-bottom : 250px ; } |
CSS
/* /src/components/Doctors.css */ .main-doc-container { display : flex; flex-wrap: wrap; justify- content : center ; align-items: center ; } .doctors-section { width : 45% ; height : 100 vh; text-align : center ; margin-left : 16px ; /* Added margin for spacing */ } /* Add the doctor card styles */ .doctor-card { background-color : #fff ; border : 1px solid #ddd ; border-radius: 8px ; padding : 16px ; margin-bottom : 16px ; box-shadow: 0 4px 8px rgba( 0 , 0 , 0 , 0.1 ); transition: transform 0.3 s ease-in-out; &:hover { transform: scale( 1.02 ); } p { margin : 0 ; } button { margin-top : 8px ; cursor : pointer ; } } /* Add the form section styles */ .form-sections { background-color : #fff ; border : 1px solid #ddd ; border-radius: 8px ; padding : 16px ; width : 45% ; margin-bottom : 306px ; box-shadow: 0 4px 8px rgba( 0 , 0 , 0 , 0.1 ); h 4 { margin-bottom : 16px ; text-align : center ; } form { display : flex; flex- direction : column; label { margin-bottom : 8px ; } input { padding : 8px ; margin-bottom : 16px ; } button { align-self: flex-start; padding : 8px ; background-color : #007bff ; color : #fff ; border : none ; border-radius: 4px ; cursor : pointer ; &:hover { background-color : #0056b3 ; } } } } button { margin-top : 8px ; cursor : pointer ; background-color : #007bff ; color : #fff ; border : none ; border-radius: 4px ; padding : 8px ; cursor : pointer ; &:hover { background-color : #0056b3 ; } } .btn-container { display : flex; justify- content : space-between; width : 100% ; } |
CSS
/* /src/components/Patients.css */ .patient-main { display : flex; } .form-sections { width : 45% ; margin-right : 20px ; height : 400px ; } .patients-section { width : 45% ; } .patient-card { background-color : #fff ; border : 1px solid #ddd ; border-radius: 8px ; padding : 16px ; margin-bottom : 16px ; box-shadow: 0 4px 8px rgba( 0 , 0 , 0 , 0.1 ); transition: transform 0.3 s ease-in-out; &:hover { transform: scale( 1.02 ); } h 4 { margin-bottom : 8px ; } p { margin : 8px 0 ; } button { margin-top : 8px ; cursor : pointer ; background-color : #007bff ; color : #fff ; border : none ; border-radius: 4px ; padding : 8px ; cursor : pointer ; &:hover { background-color : #0056b3 ; } } } /* /src/components/Patients.css */ .patient-main { display : flex; } .form-sections { width : 45% ; margin-right : 20px ; height : 400px ; } .patients-section { width : 45% ; } .patient-card { background-color : #fff ; border : 1px solid #ddd ; border-radius: 8px ; padding : 16px ; margin-bottom : 16px ; box-shadow: 0 4px 8px rgba( 0 , 0 , 0 , 0.1 ); transition: transform 0.3 s ease-in-out; &:hover { transform: scale( 1.02 ); } h 4 { margin-bottom : 8px ; } p { margin : 8px 0 ; } button { margin-top : 8px ; cursor : pointer ; background-color : #007bff ; color : #fff ; border : none ; border-radius: 4px ; padding : 8px ; cursor : pointer ; &:hover { background-color : #0056b3 ; } } } |
Steps to run the App:
To run server.js:
node server.js
To run frontend:
npm start
Output:
Data Saved in Db:
Hospital Management Application using MERN Stack
In the fast-paced world of healthcare, it’s vital to manage hospital tasks effectively to ensure top-notch patient care. This article explores creating a strong Hospital Management App using the MERN stack – that’s MongoDB, Express, React, and Node.js, breaking down the process for easier understanding.
Preview of final output: Let us have a look at how the final application will look like.