Steps to Setup Frontend with Angular
Step 1: Create Angular Project:
ng new frontend
NOTE: While creating the project, choose ‘Sass (SCSS)’ when asked ‘Which stylesheet format would you like to use?’.
Step 2: Switch to the project directory.
cd frontend
Step 3: Installing the required packages:
npm install tailwindcss @tailwindcss/forms ngx-toastr
Folder Structure(Frontend)
The updated dependencies in package.json for frontend will look like:
"dependencies": {
"@angular/animations": "^17.3.0",
"@angular/common": "^17.3.0",
"@angular/compiler": "^17.3.0",
"@angular/core": "^17.3.0",
"@angular/forms": "^17.3.0",
"@angular/platform-browser": "^17.3.0",
"@angular/platform-browser-dynamic": "^17.3.0",
"@angular/router": "^17.3.0",
"@tailwindcss/forms": "^0.5.7",
"ngx-toastr": "^18.0.0",
"rxjs": "~7.8.0",
"tailwindcss": "^3.4.3",
"zone.js": "~0.14.3"
}
Step 4: Create the Tailwind Configuration file (`tailwind.config.js`) using below command:
npx tailwindcss init
Step 5: Create a Angular Service named `api` using below command.
ng generate service api
Step 6: Add app-routing as a top-level module, load and configure the router and routes inside it.
ng generate module app-routing --flat
Step 7: Update the following files.
/* styles.scss */
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "ngx-toastr/toastr";
.required:after {
content: " *";
color: red;
}
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{html,js}"],
theme: {
extend: {},
},
plugins: [require('@tailwindcss/forms')],
};
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideHttpClient } from '@angular/common/http';
import { provideAnimations } from '@angular/platform-browser/animations';
import { provideToastr } from 'ngx-toastr';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideHttpClient(),
provideAnimations(),
provideToastr(),
],
};
// src/app/api.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class ApiService {
constructor(private http: HttpClient) { }
getPatients(): Observable<any> {
return this.http.get<any>
('http://localhost:4000/api/patient/get');
}
addPatient(data: any): Observable<any> {
return this.http.post<any>
('http://localhost:4000/api/patient/add', data);
}
updatePatient(id: string, data: any): Observable<any> {
return this.http.put<any>(
'http://localhost:4000/api/patient/update/' + id,
data
);
}
deletePatient(id: string): Observable<any> {
return this.http.delete<any>(
'http://localhost:4000/api/patient/delete/' + id
);
}
getDoctors(): Observable<any> {
return this.http.get<any>('http://localhost:4000/api/doctor/get');
}
addDoctor(data: any): Observable<any> {
return this.http.post<any>('http://localhost:4000/api/doctor/add', data);
}
updateDoctor(id: string, data: any): Observable<any> {
return this.http.put<any>(
'http://localhost:4000/api/doctor/update/' + id,
data
);
}
deleteDoctor(id: string): Observable<any> {
return this.http.delete<any>(
'http://localhost:4000/api/doctor/delete/' + id
);
}
getAppointments(): Observable<any> {
return this.http.get<any>
('http://localhost:4000/api/appointment/get');
}
addAppointment(data: any): Observable<any> {
return this.http.post<any>(
'http://localhost:4000/api/appointment/add',
data
);
}
updateAppointment(id: string, data: any): Observable<any> {
return this.http.put<any>(
'http://localhost:4000/api/appointment/update/' + id,
data
);
}
deleteAppointment(id: string): Observable<any> {
return this.http.delete<any>(
'http://localhost:4000/api/appointment/delete/' + id
);
}
}
//app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { routes } from './app.routes';
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule { }
Step 8: Create a Angular Components named `appointments`, `doctors` and `patients` inside `src/components` folder using below command.
ng generate component components/appointments
ng generate component components/doctors
ng generate component components/patients
Step 9: Below is the code for frontend.
<!-- app.component.html -->
<div class="block">
<h2 class="text-center text-3xl font-semibold
leading-7 text-green-600 mt-2">
GFG's Hospital Management Website
</h2>
</div>
<div class="text-sm font-medium text-center
text-gray-500 border-b border-gray-300">
<ul class="flex flex-wrap -mb-px">
<li class="me-2">
<button class="nav-item inline-block
p-4 text-blue-600 border-b-2 border-blue-600
rounded-t-lg active"
id="nav-appointments"
(click)="navClick('appointments')">
Appointments
</button>
</li>
<li class="me-2">
<button id="nav-doctors"
(click)="navClick('doctors')"
class="nav-item inline-block p-4
border-b-2 border-transparent rounded-t-lg
hover:text-gray-600 hover:border-gray-300">
Doctors
</button>
</li>
<li class="me-2">
<button id="nav-patients"
(click)="navClick('patients')"
class="nav-item inline-block p-4 border-b-2
border-transparent rounded-t-lg hover:text-gray-600
hover:border-gray-300">
Patients
</button>
</li>
</ul>
</div>
<router-outlet></router-outlet>
<!-- components/appointments.component.html -->
<div class="w-full flex justify-center
items-center h-screen overflow-y-hidden">
<div class="flex justify-center items-start flex-1 pt-12">
<div
class="max-w-lg w-full h-auto p-6 bg-white
border border-gray-200 rounded-lg shadow ml-2 mt-2"
>
<h2
class="text-center text-2xl font-semibold
leading-7 text-blue-600 mb-2"
>
Add New Appointment
</h2>
<form class="max-w-md mx-auto">
<div class="block mb-5">
<label
for="patient"
class="block mb-2 text-sm font-medium
text-gray-600 required"
>Patient</label
>
<select
[(ngModel)]="patient"
name="patient"
id="patient"
class="bg-gray-50 border border-gray-300
text-gray-900 text-sm rounded-lg focus:ring-blue-500
focus:border-blue-500 block w-full p-2.5"
>
<option value="Select" selected>Select</option>
<option *ngFor="let patient of PatientsArray">
{{ patient.name }}, ({{ patient.age }}) - {{ patient.gender }}
</option>
</select>
</div>
<div class="block mb-5">
<label
for="doctor"
class="block mb-2 text-sm font-medium text-gray-600 required"
>Doctor</label
>
<select
[(ngModel)]="doctor"
name="doctor"
id="doctor"
class="bg-gray-50 border border-gray-300 text-gray-900
text-sm rounded-lg focus:ring-blue-500
focus:border-blue-500 block w-full p-2.5"
>
<option value="Select" selected>Select</option>
<option *ngFor="let doctor of DoctorsArray">
{{ doctor.name }} - {{ doctor.speciality }}
</option>
</select>
</div>
<div class="block mb-5">
<label
for="appointmentDate"
class="block mb-2 text-sm font-medium
text-gray-600 required"
>Appointment Date</label
>
<input
type="date"
[(ngModel)]="appointmentDate"
name="appointmentDate"
id="appointmentDate"
class="bg-gray-50 border border-gray-300
text-gray-900 text-sm rounded-lg focus:ring-blue-500
focus:border-blue-500 block w-full p-2.5"
required
/>
</div>
<div class="block">
<button
*ngIf="!isEditing"
type="submit"
class="w-full block text-white bg-blue-700 hover:bg-blue-800
focus:ring-4 focus:ring-blue-300 font-medium
rounded-lg text-sm px-5 py-2.5 me-2"
(click)="onAddClick()"
>
Add
</button>
<button
*ngIf="isEditing"
type="submit"
class="w-full block text-white bg-blue-700
hover:bg-blue-800 focus:ring-4 focus:ring-blue-300
font-medium rounded-lg text-sm px-5 py-2.5 me-2"
(click)="onUpdateClick()"
>
Update
</button>
</div>
</form>
</div>
<div class="flex-none mx-4"></div>
<div class="flex-none w-96">
<h2
class="text-center text-2xl font-semibold
leading-7 text-blue-600 my-2"
>
Appointments ({{ AppointmentsArray.length }})
</h2>
<div class="h-screen overflow-y-auto">
<div *ngFor="let appointment of AppointmentsArray">
<div class="h-auto my-2">
<div
class="bg-white border border-gray-200 rounded-lg
shadow md:max-w-xl hover:bg-gray-100"
>
<div class="flex flex-col items-center md:flex-row">
<div class="flex flex-col justify-between p-4 leading-normal">
<p class="font-normal text-gray-700">
<b>Patient:</b> {{ appointment.patient }}
</p>
<p class="font-normal text-gray-700">
<b>Doctor:</b> {{ appointment.doctor }}
</p>
<p class="font-normal text-gray-700">
<b>Date:</b>
{{ appointment.appointmentDate | date : "fullDate" }}
</p>
</div>
</div>
<div class="flex items-center justify-center gap-x-3 mb-2">
<button
type="button"
class="rounded-md bg-yellow-500 px-5 py-2 text-sm
font-semibold text-white shadow-sm hover:bg-yellow-400
focus-visible:outline focus-visible:outline-2
focus-visible:outline-offset-2 focus-visible:outline-yellow-600"
(click)="onEditAppointment(appointment._id)"
>
Edit
</button>
<button
type="button"
class="rounded-md bg-red-600 px-3 py-2 text-sm
font-semibold text-white shadow-sm hover:bg-red-500
focus-visible:outline focus-visible:outline-2
focus-visible:outline-offset-2 focus-visible:outline-red-600"
(click)="onDeleteAppointment(appointment._id)"
>
Delete
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!--components/doctors.component.html -->
<div class="w-full flex justify-center items-center
h-screen overflow-y-hidden">
<div class="flex justify-center
items-start flex-1 pt-12">
<div
class="max-w-lg w-full h-auto p-6 bg-white
border border-gray-200 rounded-lg shadow ml-2 mt-2"
>
<h2
class="text-center text-2xl font-semibold
leading-7 text-blue-600 mb-2"
>
Add New Doctor
</h2>
<form class="max-w-md mx-auto">
<div class="block mb-5">
<label
for="name"
class="block mb-2 text-sm font-medium text-gray-600 required"
>Name</label
>
<input
type="text"
[(ngModel)]="name"
name="name"
id="name"
class="bg-gray-50 border border-gray-300 text-gray-900
text-sm rounded-lg focus:ring-blue-500
focus:border-blue-500 block w-full p-2.5"
placeholder="Doctor's Name"
required
/>
</div>
<div class="block mb-5">
<label
for="speciality"
class="block mb-2 text-sm font-medium text-gray-600 required"
>Speciality</label
>
<select
[(ngModel)]="speciality"
name="speciality"
id="speciality"
class="bg-gray-50 border border-gray-300
text-gray-900 text-sm rounded-lg focus:ring-blue-500
focus:border-blue-500 block w-full p-2.5"
>
<option value="Select" selected>Select</option>
<option value="Anesthesiologist">Anesthesiologist</option>
<option value="Cardiologist">Cardiologist</option>
<option value="Dermatologist">Dermatologist</option>
<option value="Gastroenterologist">Gastroenterologist</option>
<option value="Neurologist">Neurologist</option>
<option value="Ophthalmologist">Ophthalmologist</option>
</select>
</div>
<div class="block">
<button
*ngIf="!isEditing"
type="submit"
class="w-full block text-white bg-blue-700 hover:bg-blue-800
focus:ring-4 focus:ring-blue-300
font-medium rounded-lg text-sm px-5 py-2.5 me-2"
(click)="onAddClick()"
>
Add
</button>
<button
*ngIf="isEditing"
type="submit"
class="w-full block text-white bg-blue-700 hover:bg-blue-800
focus:ring-4 focus:ring-blue-300 font-medium
rounded-lg text-sm px-5 py-2.5 me-2"
(click)="onUpdateClick()"
>
Update
</button>
</div>
</form>
</div>
<div class="flex-none mx-4"></div>
<div class="flex-none w-96">
<h2
class="text-center text-2xl font-semibold
leading-7 text-blue-600 my-2"
>
Doctors ({{ DoctorsArray.length }})
</h2>
<div class="h-screen overflow-y-auto">
<div *ngFor="let doctor of DoctorsArray">
<div class="h-auto my-2">
<div
class="bg-white border border-gray-200 rounded-lg
shadow md:max-w-xl hover:bg-gray-100"
>
<div class="flex flex-col items-center md:flex-row">
<div class="mx-2">
<svg width="60" height="60" viewBox="0 0 122.47 122.88">
<title>Doctor</title>
<path
d="M84.58,103.47a4.09,4.09,0,1,1-4.08,4.09,
4.08,4.08,0,0,1,4.08-4.09Zm3.61-60.62a3.89,
3.89,0,0,1,2.2,1.48c1.08,1.39,1.38,3.64,1.08,
6a15.16,15.16,0,0,1-2.21,6.2c-1.31,2-3,3.29-5,
3.16-.14,6.51-3.33,9.5-7.49,13.41l-1.59,
1.51-.54.51.13.09a14.67,14.67,0,0,1-1.58,
1.1,17.71,17.71,0,0,1-4.61,2.47,20.48,20.48,
0,0,1-6.84,1.12,21.4,21.4,0,0,1-7.11-1.1l-1-.36a16.18,
16.18,0,0,1-3.74-1.66l-.5-.31a21.59,21.59,0,0,1-2.26,
4.77L62.65,92.05,77.23,79.9A22.93,22.93,0,0,1,75,75.38c6.43,
4.57,7.82,14.11,7.61,21.81,0,1-.06,1.26-.08,
1.59a8.91,8.91,0,0,0-4.36,15,8.49,8.49,0,0,0,
11.77.7,8.9,8.9,0,0,0,3.42-7,7.94,7.94,0,0,
0-1.08-4c-1.5-2.6-3.13-3.36-5.62-4.6-.17-.09,
0-.47,0-1.53a47.43,47.43,0,0,0-1.46-14.08,21,
21,0,0,0,3.4,1.41c8.9,2.1,19.84,3,23.76,5.2a16,
16,0,0,1,5,4.26c3.47,4.58,3.76,17.76,5,23.36-.31,
3.28-2.16,5.16-5.82,5.44H5.82C2.17,122.6.31,120.71,
0,117.44c1.26-5.6,1.56-18.79,5-23.36a15.58,15.58,0,
0,1,5.05-4.26c5.57-3.1,19.22-3.94,28.3-6.46a33.06,
33.06,0,0,0-1.58,8c-1,.77-3.64,1.67-4.47,2.66a38.55,
38.55,0,0,0-3.86,5.53,2,2,0,0,0-.27,1c0,
.28.29.57.17.81l-.19.37c-2.6,5-4.29,10.61-3.49,
13A3.64,3.64,0,0,0,27.3,117a12.43,12.43,0,0,0,
3.15.41c.31,0,.63,0,.94,0a3.07,3.07,0,0,0,.52.39,
4.12,4.12,0,0,0,.67.32,2.58,2.58,0,0,0,.91.17A2.51,
2.51,0,0,0,36,115.75a2.54,2.54,0,0,0-.23-1,2.58,2.58,
0,0,0-2.38-1.61c-.92,0-2.23.46-2.23,1.38v0l0,.06-.64,
0a9.17,9.17,0,0,1-2.33-.28c-.45-.12-.71-.29-.77-.48-.58-1.68,
1-6.33,3.29-10.83l.29-.55a2,2,0,0,0,1-.88,34,34,0,0,
1,3.41-4.92,7.09,7.09,0,0,1,3.38-1.72H39a10.53,10.53,
0,0,1,1.72,1.55,30.64,30.64,0,0,1,3.6,5c.23.41.79.5,1,
.89,2.65,4.28,4.14,9.19,3.78,11.06-.08.44-.44.7-1,
.88a10.49,10.49,0,0,1-2.62.37,1.74,1.74,0,0,
0-.1-.19v0c0-.92-1.32-1.35-2.24-1.38a2.58,2.58,
0,0,0-2.38,1.61,2.71,2.71,0,0,0-.23,1,2.51,2.51,0,0,
0,2.51,2.51,2.63,2.63,0,0,0,.92-.17,4,4,0,0,0,.66-.32,
3.27,3.27,0,0,0,.36-.25h.36A12.22,12.22,0,0,0,49,117a3.88,
3.88,0,0,0,2.9-3.05c.44-2.44-1.33-7.82-3.94-12.7a2,2,0,0,
0,.16-.81,2.13,2.13,0,0,0-.28-1,36,36,0,0,
0-4.1-5.7c-.83-.93-2.66-1.2-2.85-2.44-.5-3.23.9-7.23,
3-10.71a15.15,15.15,0,0,0,1.46-2.19l.32-.44a8.32,8.32,
0,0,1,3.41-2.08q-.73-.55-1.47-1.2L46.07,
73.3l-.1-.09c-4-3.48-7.41-6.43-8-13.56-2.78-.24-4
.75-2.88-5.72-6a15.2,15.2,0,0,1-.65-5.14,7.82,7.82,
0,0,1,1.51-4.56,4.31,4.31,0,0,1,.63-.65l-.14-.09c-
.64-8,1.23-21.82-7.43-24.44C42.51-1.55,60.51-5.27,
75.6,7.13,91.28,8,98.85,30.64,88.19,42.85Zm-46-5a14,
14,0,0,0-.2,7.6,1.67,1.67,0,0,1-2.67,
1.77c-2-1.7-3.21-1.86-3.73-1.24a4.7,4.7,
0,0,0-.75,2.6,11.77,11.77,0,0,0,.51,4c.68,
2.23,2,4.06,3.58,3.6a1.51,1.51,0,0,1,.48-.08,
1.67,1.67,0,0,1,1.71,1.63c.17,7,3.24,9.67,7,
12.9l.1.08,1.6,1.4a16.87,16.87,0,0,0,5.82,3.46,
17.29,17.29,0,0,0,4.44.87,25,25,0,0,0,3.35-.16,23.69,
23.69,0,0,0,4.45-.91,15,15,0,0,0,4.91-3.23l1.
62-1.54c4-3.74,6.92-6.5,6.36-13.21a1.67,1.67,
0,0,1,2.59-1.53c1.13.75,2.25,0,3.08-1.24a11.63,
11.63,0,0,0,1.69-4.78,5.27,5.27,0,0,0-.41-3.52c-
.4-.52-1.47-.31-3.53,1.26a1.67,1.67,0,0,1-2.73-1.55c1
.46-8.54.73-13.82-1.14-17.34-1.63-3-4.23-4.85-7-6.
32-6.15,4.7-10.49,5.23-14.81,5.77-3.57.44-7.12.88-
11.83,4.13a11.37,11.37,0,0,0-4.47,5.58Z"
/>
</svg>
</div>
<div class="flex flex-col justify-between p-4 leading-normal">
<h5
class="mb-2 text-2xl font-bold tracking-tight text-gray-900"
>
{{ doctor.name }}
</h5>
<p class="font-normal text-gray-700">
{{ doctor.speciality }}
</p>
</div>
</div>
<div class="flex items-center justify-center gap-x-3 mb-2">
<button
type="button"
class="rounded-md bg-yellow-500 px-5 py-2 text-sm
font-semibold text-white shadow-sm hover:bg-yellow-400
focus-visible:outline focus-visible:outline-2
focus-visible:outline-offset-2 focus-visible:outline-yellow-600"
(click)="onEditDoctor(doctor._id)"
>
Edit
</button>
<button
type="button"
class="rounded-md bg-red-600 px-3 py-2 text-sm
font-semibold text-white shadow-sm hover:bg-red-500
focus-visible:outline focus-visible:outline-2
focus-visible:outline-offset-2 focus-visible:outline-red-600"
(click)="onDeleteDoctor(doctor._id)"
>
Delete
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!--components/patients.component.html -->
<div class="w-full flex justify-center items-center
h-screen overflow-y-hidden">
<div class="flex justify-center items-start flex-1 pt-12">
<div
class="max-w-lg w-full h-auto p-6 bg-white border
border-gray-200 rounded-lg shadow ml-2 mt-2"
>
<h2
class="text-center text-2xl font-semibold
leading-7 text-blue-600 mb-2"
>
Add New Patient
</h2>
<form class="max-w-md mx-auto">
<div class="block mb-5">
<label
for="name"
class="block mb-2 text-sm font-medium
text-gray-600 required"
>Name</label
>
<input
type="text"
[(ngModel)]="name"
name="name"
id="name"
class="bg-gray-50 border border-gray-300
text-gray-900 text-sm rounded-lg focus:ring-blue-500
focus:border-blue-500 block w-full p-2.5"
placeholder="Patient's Name"
required
/>
</div>
<div class="block mb-5">
<label
for="age"
class="block mb-2 text-sm font-medium
text-gray-600 required"
>Age</label
>
<input
type="number"
[(ngModel)]="age"
name="age"
id="age"
class="bg-gray-50 border border-gray-300
text-gray-900 text-sm rounded-lg focus:ring-blue-500
focus:border-blue-500 block w-full p-2.5"
placeholder="Patient's Age"
required
/>
</div>
<div class="block mb-5">
<label
for="gender"
class="block mb-2 text-sm font-medium text-gray-600 required"
>Gender</label
>
<select
[(ngModel)]="gender"
name="gender"
id="gender"
class="bg-gray-50 border border-gray-300 text-gray-900
text-sm rounded-lg focus:ring-blue-500
focus:border-blue-500 block w-full p-2.5"
>
<option value="Select" selected>Select</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
<option value="Other">Other</option>
<option value="Prefer not to say">Prefer not to say</option>
</select>
</div>
<div class="block">
<button
*ngIf="!isEditing"
type="submit"
class="w-full block text-white bg-blue-700
hover:bg-blue-800 focus:ring-4 focus:ring-blue-300
font-medium rounded-lg text-sm px-5 py-2.5 me-2"
(click)="onAddClick()"
>
Add
</button>
<button
*ngIf="isEditing"
type="submit"
class="w-full block text-white bg-blue-700
hover:bg-blue-800 focus:ring-4 focus:ring-blue-300
font-medium rounded-lg text-sm px-5 py-2.5 me-2"
(click)="onUpdateClick()"
>
Update
</button>
</div>
</form>
</div>
<div class="flex-none mx-4"></div>
<div class="flex-none w-96">
<h2
class="text-center text-2xl font-semibold
leading-7 text-blue-600 my-2"
>
Patients ({{ PatientsArray.length }})
</h2>
<div class="h-screen overflow-y-auto">
<div *ngFor="let patient of PatientsArray">
<div class="h-auto my-2">
<div
class="bg-white border border-gray-200
rounded-lg shadow md:max-w-xl hover:bg-gray-100"
>
<div class="flex flex-col items-center md:flex-row">
<div class="flex flex-col justify-between p-4 leading-normal">
<p class="font-normal text-gray-700 text-lg">
Name: {{ patient.name }}
</p>
<p class="font-normal text-gray-700 text-lg">
Age: {{ patient.age }}
</p>
<p class="font-normal text-gray-700 text-lg">
Gender: {{ patient.gender }}
</p>
</div>
</div>
<div class="flex items-center justify-center gap-x-3 mb-2">
<button
type="button"
class="rounded-md bg-yellow-500 px-5 py-2
text-sm font-semibold text-white shadow-sm
hover:bg-yellow-400 focus-visible:outline
focus-visible:outline-2 focus-visible:outline-offset-2
focus-visible:outline-yellow-600"
(click)="onEditPatient(patient._id)"
>
Edit
</button>
<button
type="button"
class="rounded-md bg-red-600 px-3 py-2
text-sm font-semibold text-white shadow-sm
hover:bg-red-500 focus-visible:outline
focus-visible:outline-2 focus-visible:outline-offset-2
focus-visible:outline-red-600"
(click)="onDeletePatient(patient._id)"
>
Delete
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
// app.routes.ts
import { Routes } from '@angular/router';
import { AppointmentsComponent } from './components/appointments/appointments.component';
import { DoctorsComponent } from './components/doctors/doctors.component';
import { PatientsComponent } from './components/patients/patients.component';
export const routes: Routes = [
{
path: '',
redirectTo: 'appointments',
pathMatch: 'full',
},
{
path: 'appointments',
component: AppointmentsComponent,
},
{
path: 'doctors',
component: DoctorsComponent,
},
{
path: 'patients',
component: PatientsComponent,
},
];
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideHttpClient } from '@angular/common/http';
import { provideAnimations } from '@angular/platform-browser/animations';
import { provideToastr } from 'ngx-toastr';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideHttpClient(),
provideAnimations(),
provideToastr(),
],
};
// app.component.ts
import { Component } from '@angular/core';
import { RouterOutlet, Router } from '@angular/router';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet],
templateUrl: './app.component.html',
styleUrl: './app.component.css',
})
export class AppComponent {
constructor(private router: Router) { }
navClick(divId: string): void {
const navItems = document
.getElementsByClassName('nav-item');
for (let i = 0; i < navItems.length; i++) {
if (navItems[i].id === 'nav-' + divId) {
navItems[i].className =
'nav-item inline-block p-4 text-blue-600
border-b-2 border-blue-600 rounded-t-lg active';
} else {
navItems[i].className =
'nav-item inline-block p-4 border-b-2
border-transparent rounded-t-lg
hover:text-gray-600 hover:border-gray-300';
}
}
this.router.navigate(['/' + divId]);
}
}
// components/appointments.component.ts
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ToastrService } from 'ngx-toastr';
import { ApiService } from 'src/app/api.service';
@Component({
selector: 'app-appointments',
standalone: true,
imports: [CommonModule, FormsModule],
templateUrl: './appointments.component.html',
styleUrl: './appointments.component.css',
})
export class AppointmentsComponent {
patient: string = 'Select';
doctor: string = 'Select';
appointmentDate: string = '';
isEditing: boolean = false;
editAppointmentId: string = '';
DoctorsArray: any[] = [];
PatientsArray: any[] = [];
AppointmentsArray: any[] = [];
constructor(private apiService: ApiService,
private toastr: ToastrService) { }
ngOnInit(): void {
this.apiService.getPatients().subscribe((res) => {
this.PatientsArray = res;
});
this.apiService.getDoctors().subscribe((res) => {
this.DoctorsArray = res;
});
this.apiService.getAppointments().subscribe((res) => {
this.AppointmentsArray = res;
});
}
clear(): void {
this.patient = 'Select';
this.doctor = 'Select';
this.appointmentDate = '';
}
onEditAppointment(id: string): void {
const index = this.AppointmentsArray.findIndex(
(appointment) => appointment._id === id
);
const appointment = this.AppointmentsArray[index];
this.patient = appointment['patient'];
this.doctor = appointment['doctor'];
this.appointmentDate = new Date
(appointment['appointmentDate']).toISOString().slice(0, 10);
this.isEditing = true;
this.editAppointmentId = id;
}
onDeleteAppointment(id: string): void {
this.apiService.deleteAppointment(id).subscribe((res) => {
this.AppointmentsArray = this.AppointmentsArray.filter(
(appointment) => appointment._id !== id
);
this.toastr.success('Appointment deleted successfully!', 'Success!');
});
}
onAddClick(): void {
const data = {
patient: this.patient,
doctor: this.doctor,
appointmentDate: this.appointmentDate,
};
this.apiService.addAppointment(data).subscribe((res) => {
this.AppointmentsArray.push(res);
this.clear();
this.toastr.success('New Appointment added successfully', 'Success!');
});
}
onUpdateClick(): void {
const data = {
patient: this.patient,
doctor: this.doctor,
appointmentDate: this.appointmentDate,
};
this.apiService
.updateAppointment(this.editAppointmentId, data)
.subscribe((res) => {
this.AppointmentsArray = this.AppointmentsArray.filter(
(appointment) => appointment._id !== this.editAppointmentId
);
this.AppointmentsArray.push(res);
this.editAppointmentId = '';
this.isEditing = false;
this.toastr.success(
'Appointment details updated successfully',
'Success!'
);
this.clear();
});
}
}
//components/doctors.component.ts
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ToastrService } from 'ngx-toastr';
import { ApiService } from 'src/app/api.service';
@Component({
selector: 'app-doctors',
standalone: true,
imports: [CommonModule, FormsModule],
templateUrl: './doctors.component.html',
styleUrl: './doctors.component.css',
})
export class DoctorsComponent implements OnInit {
name: string = '';
speciality: string = 'Select';
isEditing: boolean = false;
editDoctorId: string = '';
DoctorsArray: any[] = [];
constructor(private apiService: ApiService,
private toastr: ToastrService) { }
ngOnInit(): void {
this.apiService.getDoctors().subscribe((res) => {
this.DoctorsArray = res;
});
}
clear(): void {
this.name = '';
this.speciality = 'Select';
}
onEditDoctor(id: string): void {
const index = this.DoctorsArray
.findIndex((doctor) => doctor._id === id);
const doctor = this.DoctorsArray[index];
this.name = doctor['name'];
this.speciality = doctor['speciality'];
this.isEditing = true;
this.editDoctorId = id;
}
onDeleteDoctor(id: string): void {
this.apiService.deleteDoctor(id).subscribe((res) => {
this.DoctorsArray = this.DoctorsArray.filter(
(doctor) => doctor._id !== id
);
this.toastr.success('Doctor deleted successfully!', 'Success!');
});
}
onAddClick(): void {
const data = {
name: this.name,
speciality: this.speciality,
};
console.log(data);
this.apiService.addDoctor(data).subscribe((res) => {
this.DoctorsArray.push(res);
this.clear();
this.toastr.success('New Doctor added successfully', 'Success!');
});
}
onUpdateClick(): void {
const data = {
name: this.name,
speciality: this.speciality,
};
console.log(data);
this.apiService.updateDoctor(this.editDoctorId, data)
.subscribe((res) => {
this.DoctorsArray = this.DoctorsArray.filter(
(doctor) => doctor._id !== this.editDoctorId
);
this.DoctorsArray.push(res);
this.editDoctorId = '';
this.isEditing = false;
this.toastr.success('Doctor details updated successfully', 'Success!');
this.clear();
});
}
}
// components/patients.component.ts
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ToastrService } from 'ngx-toastr';
import { ApiService } from 'src/app/api.service';
@Component({
selector: 'app-patients',
standalone: true,
imports: [CommonModule, FormsModule],
templateUrl: './patients.component.html',
styleUrl: './patients.component.css',
})
export class PatientsComponent implements OnInit {
name: string = '';
age: string = '';
gender: string = 'Select';
isEditing: boolean = false;
editPatientId: string = '';
PatientsArray: any[] = [];
constructor(private apiService: ApiService,
private toastr: ToastrService) { }
ngOnInit(): void {
this.apiService.getPatients().subscribe((res) => {
this.PatientsArray = res;
});
}
clear(): void {
this.name = '';
this.age = '';
this.gender = 'Select';
}
onEditPatient(id: string): void {
const index = this.PatientsArray
.findIndex((patient) => patient._id === id);
const patient = this.PatientsArray[index];
this.name = patient['name'];
this.age = patient['age'];
this.gender = patient['gender'];
this.isEditing = true;
this.editPatientId = id;
}
onDeletePatient(id: string): void {
this.apiService.deletePatient(id).subscribe((res) => {
this.PatientsArray = this.PatientsArray.filter(
(patient) => patient._id !== id
);
this.toastr.success('Patient deleted successfully!', 'Success!');
});
}
onAddClick(): void {
const data = {
name: this.name,
age: this.age,
gender: this.gender,
};
this.apiService.addPatient(data).subscribe((res) => {
this.PatientsArray.push(res);
this.clear();
this.toastr.success('New Patient added successfully', 'Success!');
});
}
onUpdateClick(): void {
const data = {
name: this.name,
age: this.age,
gender: this.gender,
};
console.log(data);
this.apiService.updatePatient(this.editPatientId, data)
.subscribe((res) => {
this.PatientsArray = this.PatientsArray.filter(
(patient) => patient._id !== this.editPatientId
);
this.PatientsArray.push(res);
this.editPatientId = '';
this.isEditing = false;
this.toastr.success('Patient details updated successfully', 'Success!');
this.clear();
});
}
}
Step 10: Start the frontend angular application.
ng serve --open
Output
MongoDB Database storing the application data:
Hospital Management System using MEAN Stack
The Hospital Management App is an important application that ensures seamless coordination to revolutionize healthcare administration. In this article, we will be creating a Hospital Management Website using the MEAN stack – i.e. MongoDB, Express, Angular, and Node.js, with step by step process for easy understanding.
Project Preview: