From fa1430fb17a22dc61234f9ce725dc42f86096105 Mon Sep 17 00:00:00 2001
From: Sk Shaifat Murshed <shaifat.murshed@sentientgeeks.com>
Date: Tue, 11 Feb 2025 11:23:45 +0530
Subject: [PATCH] Added Appointment through Calender.

---
 .../appointment-calendar.component.html       |  2 +-
 .../appointment-calendar.component.scss       |  2 +-
 .../appointment-calendar.component.ts         | 73 +++++++++++++++----
 .../appointment-calendar.module.ts            |  4 +-
 .../appointment-dialog.component.html         |  6 +-
 .../appointment-dialog.component.ts           | 57 ++++++---------
 .../appointment/appointment-routing.module.ts |  2 +-
 .../view-appointment.component.html           |  2 +-
 .../view-appointment.component.ts             | 39 +---------
 .../patient-record.component.ts               |  1 -
 .../Appoinments/Dto/AppointmentDto.cs         |  3 +-
 .../Appointments/AppointmentAppService.cs     |  7 +-
 .../Patients/PatientAppService.cs             |  2 -
 13 files changed, 100 insertions(+), 100 deletions(-)

diff --git a/angular/src/app/appointment/appointment-calendar/appointment-calendar.component.html b/angular/src/app/appointment/appointment-calendar/appointment-calendar.component.html
index 3baf9e8..6a2a294 100644
--- a/angular/src/app/appointment/appointment-calendar/appointment-calendar.component.html
+++ b/angular/src/app/appointment/appointment-calendar/appointment-calendar.component.html
@@ -1,4 +1,4 @@
-<full-calendar [options]="calendarOptions"></full-calendar>
+<full-calendar [options]="calendarOptions" style="cursor: pointer;text-decoration:none;"></full-calendar>
 
 
 <app-appointment-dialog   [selectedDate]="selectedDate"
diff --git a/angular/src/app/appointment/appointment-calendar/appointment-calendar.component.scss b/angular/src/app/appointment/appointment-calendar/appointment-calendar.component.scss
index 046747b..36a7159 100644
--- a/angular/src/app/appointment/appointment-calendar/appointment-calendar.component.scss
+++ b/angular/src/app/appointment/appointment-calendar/appointment-calendar.component.scss
@@ -5,4 +5,4 @@
 }
 .fc-daygrid-day-number {
     text-decoration: none !important;
-}
\ No newline at end of file
+}
diff --git a/angular/src/app/appointment/appointment-calendar/appointment-calendar.component.ts b/angular/src/app/appointment/appointment-calendar/appointment-calendar.component.ts
index 2620209..b16ea83 100644
--- a/angular/src/app/appointment/appointment-calendar/appointment-calendar.component.ts
+++ b/angular/src/app/appointment/appointment-calendar/appointment-calendar.component.ts
@@ -10,27 +10,28 @@ import { PagingSortResultDto } from '@proxy/dto';
 @Component({
   selector: 'app-appointment-calendar',
   templateUrl: './appointment-calendar.component.html',
-  styleUrl: './appointment-calendar.component.scss'
+  styleUrl: './appointment-calendar.component.scss',
 })
-export class AppointmentCalendarComponent implements OnInit{
+export class AppointmentCalendarComponent implements OnInit {
   appointments: any[] = [];
   params: PagingSortResultDto;
   selectedDate: string;
   isModalVisible: boolean = false;
+  appointmentIdToEdit: string;
+  isEditMode: boolean = false;
+
   constructor(private appointmentService: AppointmentService) {}
-
   ngOnInit() {
-
-    this.loadappointments({
+    this.loadAppointments({
       first: 0,
       rows: 10,
       sortField: 'id',
       sortOrder: 1,
       globalFilter: null,
-    });  }
-    loadappointments(event: any) {
-      let order = event.sortOrder == 1 ? ' asc' : ' desc';
-
+    });
+  }
+  loadAppointments(event: any) {
+    let order = event.sortOrder == 1 ? ' asc' : ' desc';
     this.params = {
       skipCount: event.first,
       maxResultCount: event.rows,
@@ -38,6 +39,7 @@ export class AppointmentCalendarComponent implements OnInit{
       search: event.globalFilter == null ? '' : event.globalFilter,
     };
     this.appointmentService.getAppointmentList(this.params).subscribe(data => {
+      debugger
       this.appointments = data.items;
       this.updateCalendarEvents();
     });
@@ -47,28 +49,67 @@ export class AppointmentCalendarComponent implements OnInit{
       initialView: 'dayGridMonth',
       plugins: [dayGridPlugin, interactionPlugin],
       events: this.appointments.map(appointment => ({
-        title: appointment.firstName + ' - ' + appointment.doctor,
-        date: appointment.dateOfAppointment
+        id: appointment.id,
+        title: `${appointment.firstName} ${appointment.lastName}`,
+        date: this.combineDateTime(appointment.dateOfAppointment, appointment.timeOfAppointment),
       })),
-      dateClick: (arg) => this.handleDateClick(arg)
+      dateClick: arg => this.handleDateClick(arg),
+      eventClick: info => this.onEventClick(info),
+      eventContent: function(arg) {
+        return {
+          html: `<div style="background-color: #3788d8; color: white; padding: 5px;cursor: pointer; border-radius: 5px;">
+                   ${arg.event.title}
+                 </div>`
+        };
+      }
     };
   }
+  combineDateTime(dateStr: string, timeStr: string): string {
+    debugger
+    if (!timeStr) return dateStr; 
+    const date = new Date(dateStr);
+    const [hours, minutes] = timeStr.split(':'); 
+    date.setHours(parseInt(hours, 10), parseInt(minutes, 10), 0);  
+    return date.toISOString();
+  }
 
   calendarOptions: CalendarOptions = {
     initialView: 'dayGridMonth',
     plugins: [dayGridPlugin, interactionPlugin],
-    dateClick: (arg) => this.handleDateClick(arg),
+    dateClick: arg => this.handleDateClick(arg),
     events: [
       { title: 'event 1', date: '2025-01-01' },
-      { title: 'event 2', date: '2025-01-02' }
-    ]
+    ],
   };
-
+  closeDialog() {
+    debugger;
+    this.isModalVisible = false;
+    this.loadAppointments({
+      first: 0,
+      rows: 10,
+      sortField: 'id',
+      sortOrder: 1,
+      globalFilter: null,
+    });
+  }
   handleDateClick(arg) {
+    debugger;
     this.selectedDate = arg.dateStr;
     this.isModalVisible = true;
+    this.isEditMode = false;
+
   }
   onModalClose() {
     this.isModalVisible = false;
+    this.isEditMode = false;
+    this.appointmentIdToEdit = "";
+
+  }
+
+  onEventClick(info: any) {
+    debugger;
+    this.appointmentIdToEdit = info.event.id;
+    this.isEditMode = true;
+    this.isModalVisible = true;
   }
 }
diff --git a/angular/src/app/appointment/appointment-calendar/appointment-calendar.module.ts b/angular/src/app/appointment/appointment-calendar/appointment-calendar.module.ts
index a216975..abe8344 100644
--- a/angular/src/app/appointment/appointment-calendar/appointment-calendar.module.ts
+++ b/angular/src/app/appointment/appointment-calendar/appointment-calendar.module.ts
@@ -6,6 +6,7 @@ import { CalendarOptions } from '@fullcalendar/core'; // useful for typechecking
 import dayGridPlugin from '@fullcalendar/daygrid';
 import { AppointmentCalendarRoutingModule } from './appointment-calendar-routing.module';
 import { AppointmentCalendarComponent } from './appointment-calendar.component';
+import { AppointmentDialogComponent } from '../appointment-dialog/appointment-dialog.component';
 
 
 @NgModule({
@@ -16,7 +17,8 @@ import { AppointmentCalendarComponent } from './appointment-calendar.component';
     CommonModule,
     AppointmentCalendarRoutingModule,
     RouterOutlet, 
-    FullCalendarModule
+    FullCalendarModule,
+    AppointmentDialogComponent
   ]
 })
 export class AppointmentCalendarModule { }
diff --git a/angular/src/app/appointment/appointment-dialog/appointment-dialog.component.html b/angular/src/app/appointment/appointment-dialog/appointment-dialog.component.html
index 7edea7c..9a22b72 100644
--- a/angular/src/app/appointment/appointment-dialog/appointment-dialog.component.html
+++ b/angular/src/app/appointment/appointment-dialog/appointment-dialog.component.html
@@ -9,8 +9,10 @@
   <div class="modal-dialog modal-lg">
     <div class="modal-content">
       <div class="modal-header py-4">
-        <h4 class="text-success mb-0 fs-1 fw-normal">{{ name }}</h4>
-        <button
+        <h4 class="text-success mb-0 fs-3 fw-normal">
+          {{ isEditMode ? 'Edit ' : 'Create ' }}{{name}}
+        </h4>
+                <button
           tabindex="0"
           type="button"
           (click)="onClose()"
diff --git a/angular/src/app/appointment/appointment-dialog/appointment-dialog.component.ts b/angular/src/app/appointment/appointment-dialog/appointment-dialog.component.ts
index d0e6a13..f1da33f 100644
--- a/angular/src/app/appointment/appointment-dialog/appointment-dialog.component.ts
+++ b/angular/src/app/appointment/appointment-dialog/appointment-dialog.component.ts
@@ -49,13 +49,13 @@ import { CommonModule } from '@angular/common';
   templateUrl: './appointment-dialog.component.html',
   styleUrl: './appointment-dialog.component.scss',
 })
-export class AppointmentDialogComponent implements OnInit,OnChanges {
+export class AppointmentDialogComponent implements OnInit, OnChanges {
   @Input() visible: boolean = false; // Control modal visibility
   @Input() name: string;
   @Input() isEditMode: boolean = false; // Determine if it's for edit or create
   @Output() save = new EventEmitter<any>(); // Event emitter for saving appointment
   @Output() close = new EventEmitter<void>(); // Event emitter for closing the modal
-  @Input() appointmentId: string;  // To accept the appointment ID from the parent
+  @Input() appointmentId: string; // To accept the appointment ID from the parent
   @Input() selectedDate: string;
   appointmentsForDate: any[] = [];
 
@@ -63,8 +63,8 @@ export class AppointmentDialogComponent implements OnInit,OnChanges {
   AppointmentDialogTitle: string = '';
   AppointmentDialog: boolean = false;
   genders = Gender;
-  Dateofbirth: Date = new Date();
-  AppointmentDate: Date = new Date();
+  Dateofbirth: Date = null;
+  AppointmentDate: Date = null;
   doctors = [];
   doctorOptions = [];
   constructor(
@@ -76,9 +76,10 @@ export class AppointmentDialogComponent implements OnInit,OnChanges {
   ) {}
 
   ngOnInit(): void {
-    debugger;
     this.getdoctorlist();
     if (!this.isEditMode) {
+      this.appointmentId = '';
+
       this.appointment = {
         firstName: '',
         lastName: '',
@@ -98,30 +99,25 @@ export class AppointmentDialogComponent implements OnInit,OnChanges {
         insuranceProvider: '',
       };
     }
+    else{
+      this.fetchAppointmentData();
+
+    }
   }
-ngOnChanges(changes: SimpleChanges): void {
-  if (changes['appointmentId'] && this.appointmentId) {
-    // When the appointment ID changes, fetch the appointment details
-    this.fetchAppointmentData();
+  ngOnChanges(changes: SimpleChanges): void {
+
+    // if (changes['appointmentId'] && this.appointmentId) {
+    //   this.fetchAppointmentData();
+    // }
   }
-  if (changes['selectedDate'] && this.selectedDate) {
-    this.fetchAppointmentsForDate();
+
+  fetchAppointmentData() {
+    this.AppointmentService.getAppointmentById(this.appointmentId).subscribe(result => {
+      this.appointment = result;
+      this.AppointmentDate = new Date(result.dateOfAppointment);
+      this.Dateofbirth = new Date(result.dob);
+    });
   }
-}
-fetchAppointmentsForDate() {
-  // this.AppointmentService.getAppointmentsByDate(this.selectedDate).subscribe((data: any[]) => {
-  //   this.appointmentsForDate = data;
-  // });
-  debugger
-}
-fetchAppointmentData() {
-  // Fetch data based on appointment ID
-  this.AppointmentService.getAppointmentById(this.appointmentId).subscribe(result => {
-    this.appointment = result;
-    this.AppointmentDate = new Date(result.dateOfAppointment);
-    this.Dateofbirth = new Date(result.dob);
-  });
-}
   appointment: CreateOrUpdateAppointmentDto = {
     id: '',
     firstName: '',
@@ -143,7 +139,6 @@ fetchAppointmentData() {
   };
 
   saveAppointment(form: NgForm) {
-    debugger;
     if (form.invalid) {
       Object.values(form.controls).forEach(control => control.markAsTouched());
       return;
@@ -155,11 +150,9 @@ fetchAppointmentData() {
         () => {
           this.toaster.success('Appointment updated successfully', 'Success');
           this.AppointmentDialog = false;
-
           this.onClose();
         },
         error => {
-          console.log(error);
           this.toaster.error(error, 'Error');
         }
       );
@@ -172,7 +165,6 @@ fetchAppointmentData() {
           this.onClose();
         },
         error => {
-          console.log(error);
           this.toaster.error(error, 'Error');
         }
       );
@@ -207,9 +199,8 @@ fetchAppointmentData() {
     }));
 
   onClose() {
-    debugger;
     this.AppointmentDialog = false;
-
-    this.close.emit(); // Emit close event
+    this.appointmentId = '';
+    this.close.emit();
   }
 }
diff --git a/angular/src/app/appointment/appointment-routing.module.ts b/angular/src/app/appointment/appointment-routing.module.ts
index 35e2833..7d3a75a 100644
--- a/angular/src/app/appointment/appointment-routing.module.ts
+++ b/angular/src/app/appointment/appointment-routing.module.ts
@@ -10,7 +10,7 @@ const routes: Routes = [
         loadChildren: () => import('./appointment-calendar/appointment-calendar.module').then(m => m.AppointmentCalendarModule)
       },
       {
-        path: 'view-appointment',
+        path: 'view-appointment:date',
         loadChildren: () => import('./view-appointment/view-appointment.module').then(m => m.ViewAppointmentModule)
       },
     
diff --git a/angular/src/app/appointment/view-appointment/view-appointment.component.html b/angular/src/app/appointment/view-appointment/view-appointment.component.html
index 5aa0300..55337fe 100644
--- a/angular/src/app/appointment/view-appointment/view-appointment.component.html
+++ b/angular/src/app/appointment/view-appointment/view-appointment.component.html
@@ -82,7 +82,7 @@
     <ng-template pTemplate="body" let-appointment>
       <tr>
         <td>{{ appointment.firstName }} {{ appointment.lastName }}</td>
-        <td>{{ appointment.doctor }}</td>
+        <td>Dr. {{ appointment.doctor.firstName }} {{ appointment.doctor.lastName }}</td>
         <td>
           <span class="badge" [ngClass]="appointment.gender === 1 ? 'bg-primary' : 'bg-pink'">
             {{ getGenderLabel(appointment.gender) }}
diff --git a/angular/src/app/appointment/view-appointment/view-appointment.component.ts b/angular/src/app/appointment/view-appointment/view-appointment.component.ts
index 55f7164..1d92571 100644
--- a/angular/src/app/appointment/view-appointment/view-appointment.component.ts
+++ b/angular/src/app/appointment/view-appointment/view-appointment.component.ts
@@ -117,7 +117,6 @@ export class ViewAppointmentComponent {
 
     this.AppointmentService.getAppointmentList(this.params).subscribe(data => {
       this.appointments = data.items;
-      debugger;
       this.totalRecords = data.totalCount;
       this.loading = false;
     });
@@ -125,30 +124,10 @@ export class ViewAppointmentComponent {
   openNewAppointmentDialog() {
     this.isModalVisible=true;
     this.isEditMode = false;
-    //this.AppointmentDialog = true;
-    // this.appointment = {
-    //   firstName: '',
-    //   lastName: '',
-    //   email: '',
-    //   gender: Gender.Male,
-    //   dateOfAppointment: '',
-    //   dob: '',
-    //   timeOfAppointment: '',
-    //   mobile: '',
-    //   injuryORContion: '',
-    //   note: '',
-    //   doctorId: '',
-    //   address: '',
-    //   appointmentStatus: null,
-    //   visitType: null,
-    //   paymentStatus: null,
-    //   insuranceProvider: '',
-    // };
   }
 
 
   exportAppointments() {
-    debugger
     this.AppointmentService.getExportAppointmentRecord().subscribe(result => {
       const binary = atob(result.fileContent);
       const len = binary.length;
@@ -174,19 +153,9 @@ export class ViewAppointmentComponent {
     });
   }
   editAppointment(appointment: any) {
-    debugger;
     this.isEditMode = true;
     this.appointmentIdToEdit = appointment.id;  
     this.isModalVisible=true;
-
-    // this.AppointmentDialog = true;
-    // this.isModalVisible=true;
-    // this.AppointmentService.getAppointmentById(appointment.id).subscribe(result => {
-    //   debugger;
-    //   this.appointment = result;
-    //   this.AppointmentDate = new Date(result.dateOfAppointment);
-    //   this.Dateofbirth = new Date(result.dob);
-    // });
   }
 
   deleteAppointment(id: string) {
@@ -207,7 +176,6 @@ export class ViewAppointmentComponent {
   }
  
   closeDialog() {
-    debugger
     this.isModalVisible = false;
     this.loadappointments({
       first: 0,
@@ -219,17 +187,14 @@ export class ViewAppointmentComponent {
   }
   getdoctorlist() {
     this.DoctorService.get().subscribe(result => {
-      debugger;
       this.doctors = result;
       this.doctorOptions = this.doctors.map(doctor => ({
         label: `Dr. ${doctor.firstName} ${doctor.lastName}`, // Combine first and last name
-        value: doctor.id, // Use the ID as the value
+        value: doctor.id,
       }));
     });
   }
   saveAppointment(appointmentData: any) {
-    // Save appointment logic here
-    console.log('Appointment saved:', appointmentData);
-    this.closeDialog();  // Close the dialog after saving
+    this.closeDialog(); 
   }
 }
diff --git a/angular/src/app/patients/patient-record/patient-record.component.ts b/angular/src/app/patients/patient-record/patient-record.component.ts
index 62faa12..9e11bbf 100644
--- a/angular/src/app/patients/patient-record/patient-record.component.ts
+++ b/angular/src/app/patients/patient-record/patient-record.component.ts
@@ -190,7 +190,6 @@ export class PatientRecordComponent implements OnInit {
     this.patientDialogTitle = 'Edit Patient';
     this.patientService.getPatientRecordById(Patient.id).subscribe(result => {
       this.selectedPatientRecord = result;
-      console.log(result);
       this.selectedPatientRecord.patientId = this.patientId;
       this.selectdateOfAdmission = new Date(this.selectedPatientRecord.dateOfAdmission);
       this.selectnextFollowUp = new Date(this.selectedPatientRecord.nextFollowUp);
diff --git a/aspnet-core/src/HospitalManagementSystem.Application.Contracts/Appoinments/Dto/AppointmentDto.cs b/aspnet-core/src/HospitalManagementSystem.Application.Contracts/Appoinments/Dto/AppointmentDto.cs
index 61f6ad9..13044cf 100644
--- a/aspnet-core/src/HospitalManagementSystem.Application.Contracts/Appoinments/Dto/AppointmentDto.cs
+++ b/aspnet-core/src/HospitalManagementSystem.Application.Contracts/Appoinments/Dto/AppointmentDto.cs
@@ -1,4 +1,5 @@
 using HospitalManagementSystem.Doctors;
+using HospitalManagementSystem.Doctors.Dto;
 using HospitalManagementSystem.GlobalEnum;
 using System;
 using System.Collections.Generic;
@@ -27,7 +28,7 @@ namespace HospitalManagementSystem.Appoinments.Dto
         public appointmentStatus AppointmentStatus { get; set; }
         public visitType VisitType { get; set; }
         public paymentStatus PaymentStatus { get; set; }
-        public  Doctor? Doctor { get; set; }
+        public  DoctorDto? Doctor { get; set; }
 
     }
 }
diff --git a/aspnet-core/src/HospitalManagementSystem.Application/Appointments/AppointmentAppService.cs b/aspnet-core/src/HospitalManagementSystem.Application/Appointments/AppointmentAppService.cs
index bf885fe..59c0f5a 100644
--- a/aspnet-core/src/HospitalManagementSystem.Application/Appointments/AppointmentAppService.cs
+++ b/aspnet-core/src/HospitalManagementSystem.Application/Appointments/AppointmentAppService.cs
@@ -54,6 +54,7 @@ namespace HospitalManagementSystem.Appointments
             var queryable = await _appointmentsRepository.GetQueryableAsync();
 
             var filteredQuery = queryable
+                .Include(x => x.Doctor)
                 .WhereIf(!string.IsNullOrEmpty(input.Search), x => x.FirstName.ToLower().Contains(input.Search.ToLower()) || x.LastName.ToLower().Contains(input.Search.ToLower()));
 
             var totalCount = await filteredQuery.CountAsync();
@@ -78,7 +79,7 @@ namespace HospitalManagementSystem.Appointments
         #region Get Appointment by ID
         public async Task<AppointmentDto> GetAppointmentByIdAsync(Guid id)
         {
-            var appointment = await _appointmentsRepository.FirstOrDefaultAsync(x => x.Id == id);
+            var appointment = await _appointmentsRepository.GetQueryableAsync().Result.Include(a => a.Doctor).FirstOrDefaultAsync(x => x.Id == id);
 
             if (appointment == null)
             {
@@ -131,7 +132,7 @@ namespace HospitalManagementSystem.Appointments
         #region Export Appointment Data to Excel
         public async Task<FileDownloadDto> GetExportAppointmentRecordAsync()
         {
-            var Appointmentrecord = await _appointmentsRepository.GetQueryableAsync().Result.ToListAsync();
+            var Appointmentrecord = await _appointmentsRepository.GetQueryableAsync().Result.Include(a=>a.Doctor).ToListAsync();
 
             var folderPath = Path.Combine(_env.WebRootPath, "temp");
             if (!Directory.Exists(folderPath))
@@ -170,7 +171,7 @@ namespace HospitalManagementSystem.Appointments
                     worksheet.Cell(i + 2, 4).Value = Appointmentrecord[i].DateOfAppointment?.ToShortDateString();
                     worksheet.Cell(i + 2, 5).Value = Appointmentrecord[i].TimeOfAppointment;
                     worksheet.Cell(i + 2, 6).Value = Appointmentrecord[i].Mobile;
-                    worksheet.Cell(i + 2, 7).Value = "";
+                    worksheet.Cell(i + 2, 7).Value = "Dr. " +Appointmentrecord[i].Doctor.FirstName+" "+ Appointmentrecord[i].Doctor.LastName;
                     worksheet.Cell(i + 2, 8).Value = Appointmentrecord[i].InjuryORContion;
                     worksheet.Cell(i + 2, 9).Value = Appointmentrecord[i].AppointmentStatus.ToString();
                     worksheet.Cell(i + 2, 10).Value = Appointmentrecord[i].VisitType.ToString();
diff --git a/aspnet-core/src/HospitalManagementSystem.Application/Patients/PatientAppService.cs b/aspnet-core/src/HospitalManagementSystem.Application/Patients/PatientAppService.cs
index 75a8863..0ac620a 100644
--- a/aspnet-core/src/HospitalManagementSystem.Application/Patients/PatientAppService.cs
+++ b/aspnet-core/src/HospitalManagementSystem.Application/Patients/PatientAppService.cs
@@ -65,11 +65,9 @@ namespace HospitalManagementSystem.Patients
                 .Where(x => x.Patients.Id == Id);
 
             var totalCount = await filteredQuery.CountAsync();
-
             filteredQuery = !string.IsNullOrEmpty(input.Sorting)
                 ? filteredQuery.OrderBy(input.Sorting)
                 : filteredQuery.OrderBy(x => x.Id);
-
             var pagedQuery = await filteredQuery
                 .Skip(input.SkipCount)
                 .Take(input.MaxResultCount)