hospital management system
import React, { useState, createContext, useContext } from 'react';
// --- Context for managing hospital data ---
const HospitalContext = createContext(null);
const HospitalProvider = ({ children }) => {
// Initial dummy data for demonstration
const [patients, setPatients] = useState([
{ id: 'PAT001', name: 'Alice Smith', age: 30, gender: 'Female', medicalHistory: 'Flu symptoms' },
{ id: 'PAT002', name: 'Bob Johnson', age: 45, gender: 'Male', medicalHistory: 'Routine check-up' },
]);
const [doctors, setDoctors] = useState([
{ id: 'DOC001', name: 'Dr. Emily White', specialization: 'General Physician', contactInfo: 'emily.w@hospital.com' },
{ id: 'DOC002', name: 'Dr. John Davis', specialization: 'Pediatrician', contactInfo: 'john.d@hospital.com' },
]);
const [appointments, setAppointments] = useState([
{ id: 'APP001', patientId: 'PAT001', doctorId: 'DOC001', date: '2025-06-20', time: '10:00 AM', purpose: 'Consultation' },
{ id: 'APP002', patientId: 'PAT002', doctorId: 'DOC002', date: '2025-06-21', time: '02:30 PM', purpose: 'Vaccination' },
]);
// Helper to find a patient by ID
const getPatientById = (id) => patients.find(p => p.id === id);
// Helper to find a doctor by ID
const getDoctorById = (id) => doctors.find(d => d.id === id);
// --- CRUD Operations ---
const addPatient = (newPatient) => {
setPatients([...patients, { ...newPatient, id: generateId('PAT') }]);
};
const addDoctor = (newDoctor) => {
setDoctors([...doctors, { ...newDoctor, id: generateId('DOC') }]);
};
const addAppointment = (newAppointment) => {
setAppointments([...appointments, { ...newAppointment, id: generateId('APP') }]);
};
// Simple ID generator
const generateId = (prefix) => {
return `${prefix}${Math.random().toString(36).substr(2, 6).toUpperCase()}`;
};
return (
<HospitalContext.Provider value={{
patients,
doctors,
appointments,
addPatient,
addDoctor,
addAppointment,
getPatientById,
getDoctorById
}}>
{children}
</HospitalContext.Provider>
);
};
// --- Common UI Components ---
const Card = ({ title, children }) => (
<div className="bg-white p-6 rounded-xl shadow-lg border border-gray-200 w-full">
<h2 className="text-2xl font-semibold text-gray-800 mb-4 border-b pb-2">{title}</h2>
{children}
</div>
);
const InputField = ({ label, type = 'text', value, onChange, placeholder, required = false }) => (
<div className="mb-4">
<label className="block text-gray-700 text-sm font-medium mb-2">{label}</label>
<input
type={type}
value={value}
onChange={onChange}
placeholder={placeholder}
required={required}
className="shadow appearance-none border rounded-lg w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent transition duration-200"
/>
</div>
);
const SelectField = ({ label, value, onChange, options, required = false }) => (
<div className="mb-4">
<label className="block text-gray-700 text-sm font-medium mb-2">{label}</label>
<select
value={value}
onChange={onChange}
required={required}
className="shadow border rounded-lg w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent transition duration-200 bg-white"
>
<option value="">Select an option</option>
{options.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
</div>
);
const Button = ({ onClick, children, className = '' }) => (
<button
onClick={onClick}
className={`bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-75 transition duration-200 ${className}`}
>
{children}
</button>
);
// --- Feature Components ---
const Dashboard = () => {
const { patients, doctors, appointments } = useContext(HospitalContext);
return (
<div className="flex flex-col md:flex-row gap-6 p-6">
<Card title="System Overview">
<p className="text-gray-700 mb-2">Welcome to the Hospital Management System!</p>
<p className="text-gray-700 mb-2">Manage patient records, doctor details, and appointments efficiently.</p>
<div className="mt-4 grid grid-cols-1 md:grid-cols-3 gap-4 text-center">
<div className="bg-blue-100 p-4 rounded-lg shadow-sm">
<p className="text-4xl font-bold text-blue-800">{patients.length}</p>
<p className="text-blue-700">Total Patients</p>
</div>
<div className="bg-green-100 p-4 rounded-lg shadow-sm">
<p className="text-4xl font-bold text-green-800">{doctors.length}</p>
<p className="text-green-700">Total Doctors</p>
</div>
<div className="bg-purple-100 p-4 rounded-lg shadow-sm">
<p className="text-4xl font-bold text-purple-800">{appointments.length}</p>
<p className="text-purple-700">Total Appointments</p>
</div>
</div>
</Card>
</div>
);
};
const PatientManagement = () => {
const { patients, addPatient } = useContext(HospitalContext);
const [name, setName] = useState('');
const [age, setAge] = useState('');
const [gender, setGender] = useState('');
const [medicalHistory, setMedicalHistory] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
if (!name || !age || !gender || !medicalHistory) {
alert('Please fill in all fields.'); // Using alert for simplicity, replace with custom modal
return;
}
if (isNaN(age) || parseInt(age) <= 0) {
alert('Age must be a positive number.'); // Using alert for simplicity
return;
}
addPatient({ name, age: parseInt(age), gender, medicalHistory });
setName('');
setAge('');
setGender('');
setMedicalHistory('');
alert('Patient added successfully!'); // Using alert for simplicity
};
return (
<div className="flex flex-col gap-6 p-6">
<Card title="Add New Patient">
<form onSubmit={handleSubmit}>
<InputField label="Name" value={name} onChange={(e) => setName(e.target.value)} placeholder="Patient's Full Name" required />
<InputField label="Age" type="number" value={age} onChange={(e) => setAge(e.target.value)} placeholder="Patient's Age" required />
<InputField label="Gender" value={gender} onChange={(e) => setGender(e.target.value)} placeholder="Male/Female/Other" required />
<InputField label="Medical History" value={medicalHistory} onChange={(e) => setMedicalHistory(e.target.value)} placeholder="Brief medical history" required />
<Button type="submit">Add Patient</Button>
</form>
</Card>
<Card title="All Patients">
{patients.length === 0 ? (
<p className="text-gray-600">No patients registered yet.</p>
) : (
<div className="overflow-x-auto">
<table className="min-w-full bg-white rounded-lg overflow-hidden border border-gray-200">
<thead className="bg-gray-100">
<tr>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">ID</th>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">Name</th>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">Age</th>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">Gender</th>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">Medical History</th>
</tr>
</thead>
<tbody>
{patients.map((patient) => (
<tr key={patient.id} className="hover:bg-gray-50 border-b last:border-b-0">
<td className="py-3 px-4 text-gray-800 text-sm">{patient.id}</td>
<td className="py-3 px-4 text-gray-800 text-sm">{patient.name}</td>
<td className="py-3 px-4 text-gray-800 text-sm">{patient.age}</td>
<td className="py-3 px-4 text-gray-800 text-sm">{patient.gender}</td>
<td className="py-3 px-4 text-gray-800 text-sm">{patient.medicalHistory}</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</Card>
</div>
);
};
const DoctorManagement = () => {
const { doctors, addDoctor } = useContext(HospitalContext);
const [name, setName] = useState('');
const [specialization, setSpecialization] = useState('');
const [contactInfo, setContactInfo] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
if (!name || !specialization || !contactInfo) {
alert('Please fill in all fields.'); // Using alert for simplicity
return;
}
addDoctor({ name, specialization, contactInfo });
setName('');
setSpecialization('');
setContactInfo('');
alert('Doctor added successfully!'); // Using alert for simplicity
};
return (
<div className="flex flex-col gap-6 p-6">
<Card title="Add New Doctor">
<form onSubmit={handleSubmit}>
<InputField label="Name" value={name} onChange={(e) => setName(e.target.value)} placeholder="Doctor's Full Name" required />
<InputField label="Specialization" value={specialization} onChange={(e) => setSpecialization(e.target.value)} placeholder="e.g., Cardiology, Pediatrics" required />
<InputField label="Contact Info" value={contactInfo} onChange={(e) => setContactInfo(e.target.value)} placeholder="Email or Phone" required />
<Button type="submit">Add Doctor</Button>
</form>
</Card>
<Card title="All Doctors">
{doctors.length === 0 ? (
<p className="text-gray-600">No doctors registered yet.</p>
) : (
<div className="overflow-x-auto">
<table className="min-w-full bg-white rounded-lg overflow-hidden border border-gray-200">
<thead className="bg-gray-100">
<tr>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">ID</th>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">Name</th>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">Specialization</th>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">Contact Info</th>
</tr>
</thead>
<tbody>
{doctors.map((doctor) => (
<tr key={doctor.id} className="hover:bg-gray-50 border-b last:border-b-0">
<td className="py-3 px-4 text-gray-800 text-sm">{doctor.id}</td>
<td className="py-3 px-4 text-gray-800 text-sm">{doctor.name}</td>
<td className="py-3 px-4 text-gray-800 text-sm">{doctor.specialization}</td>
<td className="py-3 px-4 text-gray-800 text-sm">{doctor.contactInfo}</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</Card>
</div>
);
};
const AppointmentScheduling = () => {
const { patients, doctors, appointments, addAppointment, getPatientById, getDoctorById } = useContext(HospitalContext);
const [selectedPatientId, setSelectedPatientId] = useState('');
const [selectedDoctorId, setSelectedDoctorId] = useState('');
const [date, setDate] = useState('');
const [time, setTime] = useState('');
const [purpose, setPurpose] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
if (!selectedPatientId || !selectedDoctorId || !date || !time || !purpose) {
alert('Please fill in all fields.'); // Using alert for simplicity
return;
}
const patient = getPatientById(selectedPatientId);
const doctor = getDoctorById(selectedDoctorId);
if (!patient || !doctor) {
alert('Selected patient or doctor not found. This should not happen with valid IDs.');
return;
}
addAppointment({ patientId: selectedPatientId, doctorId: selectedDoctorId, date, time, purpose });
setSelectedPatientId('');
setSelectedDoctorId('');
setDate('');
setTime('');
setPurpose('');
alert('Appointment scheduled successfully!'); // Using alert for simplicity
};
const patientOptions = patients.map(p => ({ value: p.id, label: `${p.name} (ID: ${p.id})` }));
const doctorOptions = doctors.map(d => ({ value: d.id, label: `${d.name} (${d.specialization})` }));
return (
<div className="flex flex-col gap-6 p-6">
<Card title="Schedule New Appointment">
<form onSubmit={handleSubmit}>
<SelectField
label="Select Patient"
value={selectedPatientId}
onChange={(e) => setSelectedPatientId(e.target.value)}
options={patientOptions}
required
/>
<SelectField
label="Select Doctor"
value={selectedDoctorId}
onChange={(e) => setSelectedDoctorId(e.target.value)}
options={doctorOptions}
required
/>
<InputField label="Date" type="date" value={date} onChange={(e) => setDate(e.target.value)} required />
<InputField label="Time" type="time" value={time} onChange={(e) => setTime(e.target.value)} required />
<InputField label="Purpose" value={purpose} onChange={(e) => setPurpose(e.target.value)} placeholder="e.g., Follow-up, Check-up" required />
<Button type="submit">Schedule Appointment</Button>
</form>
</Card>
<Card title="All Appointments">
{appointments.length === 0 ? (
<p className="text-gray-600">No appointments scheduled yet.</p>
) : (
<div className="overflow-x-auto">
<table className="min-w-full bg-white rounded-lg overflow-hidden border border-gray-200">
<thead className="bg-gray-100">
<tr>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">ID</th>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">Patient</th>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">Doctor</th>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">Date</th>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">Time</th>
<th className="py-3 px-4 text-left text-sm font-semibold text-gray-700 border-b">Purpose</th>
</tr>
</thead>
<tbody>
{appointments.map((appointment) => {
const patient = getPatientById(appointment.patientId);
const doctor = getDoctorById(appointment.doctorId);
return (
<tr key={appointment.id} className="hover:bg-gray-50 border-b last:border-b-0">
<td className="py-3 px-4 text-gray-800 text-sm">{appointment.id}</td>
<td className="py-3 px-4 text-gray-800 text-sm">{patient ? patient.name : 'N/A'}</td>
<td className="py-3 px-4 text-gray-800 text-sm">{doctor ? doctor.name : 'N/A'}</td>
<td className="py-3 px-4 text-gray-800 text-sm">{appointment.date}</td>
<td className="py-3 px-4 text-gray-800 text-sm">{appointment.time}</td>
<td className="py-3 px-4 text-gray-800 text-sm">{appointment.purpose}</td>
</tr>
);
})}
</tbody>
</table>
</div>
)}
</Card>
</div>
);
};
// --- Main App Component ---
export default function App() {
const [currentPage, setCurrentPage] = useState('dashboard'); // State to manage current view
const renderPage = () => {
switch (currentPage) {
case 'dashboard':
return <Dashboard />;
case 'patients':
return <PatientManagement />;
case 'doctors':
return <DoctorManagement />;
case 'appointments':
return <AppointmentScheduling />;
default:
return <Dashboard />;
}
};
return (
<HospitalProvider>
<div className="min-h-screen bg-gray-50 font-sans text-gray-900">
{/* Navigation Bar */}
<nav className="bg-gradient-to-r from-blue-700 to-blue-900 shadow-lg py-4 px-6 flex flex-col md:flex-row justify-between items-center rounded-b-xl">
<h1 className="text-3xl font-extrabold text-white mb-4 md:mb-0">Hospital Management</h1>
<div className="flex flex-wrap justify-center gap-4">
<NavLink text="Dashboard" page="dashboard" currentPage={currentPage} setCurrentPage={setCurrentPage} />
<NavLink text="Patients" page="patients" currentPage={currentPage} setCurrentPage={setCurrentPage} />
<NavLink text="Doctors" page="doctors" currentPage={currentPage} setCurrentPage={setCurrentPage} />
<NavLink text="Appointments" page="appointments" currentPage={currentPage} setCurrentPage={setCurrentPage} />
</div>
</nav>
{/* Main Content Area */}
<main className="container mx-auto py-8">
{renderPage()}
</main>
{/* Footer */}
<footer className="bg-gray-800 text-white text-center py-4 mt-8 rounded-t-xl">
<p>© 2025 Hospital Management System. All rights reserved.</p>
</footer>
</div>
</HospitalProvider>
);
}
// NavLink component for navigation items
const NavLink = ({ text, page, currentPage, setCurrentPage }) => (
<button
onClick={() => setCurrentPage(page)}
className={`px-4 py-2 rounded-lg text-white font-medium transition duration-300 ease-in-out
${currentPage === page ? 'bg-blue-500 shadow-md transform scale-105' : 'hover:bg-blue-600'}`}
>
{text}
</button>
);
Comments
Post a Comment