Compare commits
6 Commits
aec173f9f4
...
6a241003db
Author | SHA1 | Date | |
---|---|---|---|
6a241003db | |||
33421a3d2a | |||
9c376a64b9 | |||
79cadbf9b7 | |||
d975c46a6f | |||
5b86b58104 |
@ -39,20 +39,7 @@ const routes: Routes = [
|
||||
m => m.ViewAppointmentModule
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'appointment/book-appointment',
|
||||
loadChildren: () =>
|
||||
import('./appointment/book-appointment/book-appointment.module').then(
|
||||
m => m.BookAppointmentModule
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'appointment/edit-appointment',
|
||||
loadChildren: () =>
|
||||
import('./appointment/edit-appointment/edit-appointment.module').then(
|
||||
m => m.EditAppointmentModule
|
||||
),
|
||||
},
|
||||
|
||||
{
|
||||
path: 'patients',
|
||||
loadChildren: () => import('./patients/patients.module').then(m => m.PatientsModule),
|
||||
|
@ -1 +1,6 @@
|
||||
<full-calendar [options]="calendarOptions"></full-calendar>
|
||||
|
||||
|
||||
<app-appointment-dialog [selectedDate]="selectedDate"
|
||||
[appointmentId]="appointmentIdToEdit"[isEditMode]="isEditMode"
|
||||
[visible]="isModalVisible"*ngIf="isModalVisible" [name]="'Appointment'" (close)="closeDialog()"></app-appointment-dialog>
|
||||
|
@ -1,16 +1,59 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
import { FullCalendarModule } from '@fullcalendar/angular';
|
||||
import { CalendarOptions } from '@fullcalendar/core'; // useful for typechecking
|
||||
import dayGridPlugin from '@fullcalendar/daygrid';
|
||||
import interactionPlugin from '@fullcalendar/interaction';
|
||||
import { AppointmentService } from '@proxy/appointments';
|
||||
import { PagingSortResultDto } from '@proxy/dto';
|
||||
|
||||
@Component({
|
||||
selector: 'app-appointment-calendar',
|
||||
templateUrl: './appointment-calendar.component.html',
|
||||
styleUrl: './appointment-calendar.component.scss'
|
||||
})
|
||||
export class AppointmentCalendarComponent {
|
||||
export class AppointmentCalendarComponent implements OnInit{
|
||||
appointments: any[] = [];
|
||||
params: PagingSortResultDto;
|
||||
selectedDate: string;
|
||||
isModalVisible: boolean = false;
|
||||
constructor(private appointmentService: AppointmentService) {}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
this.loadappointments({
|
||||
first: 0,
|
||||
rows: 10,
|
||||
sortField: 'id',
|
||||
sortOrder: 1,
|
||||
globalFilter: null,
|
||||
}); }
|
||||
loadappointments(event: any) {
|
||||
let order = event.sortOrder == 1 ? ' asc' : ' desc';
|
||||
|
||||
this.params = {
|
||||
skipCount: event.first,
|
||||
maxResultCount: event.rows,
|
||||
sorting: event.sortField + order,
|
||||
search: event.globalFilter == null ? '' : event.globalFilter,
|
||||
};
|
||||
this.appointmentService.getAppointmentList(this.params).subscribe(data => {
|
||||
this.appointments = data.items;
|
||||
this.updateCalendarEvents();
|
||||
});
|
||||
}
|
||||
updateCalendarEvents() {
|
||||
this.calendarOptions = {
|
||||
initialView: 'dayGridMonth',
|
||||
plugins: [dayGridPlugin, interactionPlugin],
|
||||
events: this.appointments.map(appointment => ({
|
||||
title: appointment.firstName + ' - ' + appointment.doctor,
|
||||
date: appointment.dateOfAppointment
|
||||
})),
|
||||
dateClick: (arg) => this.handleDateClick(arg)
|
||||
};
|
||||
}
|
||||
|
||||
calendarOptions: CalendarOptions = {
|
||||
initialView: 'dayGridMonth',
|
||||
plugins: [dayGridPlugin, interactionPlugin],
|
||||
@ -22,6 +65,10 @@ export class AppointmentCalendarComponent {
|
||||
};
|
||||
|
||||
handleDateClick(arg) {
|
||||
alert('date click! ' + arg.dateStr)
|
||||
this.selectedDate = arg.dateStr;
|
||||
this.isModalVisible = true;
|
||||
}
|
||||
onModalClose() {
|
||||
this.isModalVisible = false;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,372 @@
|
||||
<div
|
||||
class="modal fade show d-block"
|
||||
tabindex="-1"
|
||||
role="dialog"
|
||||
style="background: rgba(0, 0, 0, 0.5)"
|
||||
*ngIf="visible"
|
||||
aria-label="l('name')"
|
||||
>
|
||||
<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
|
||||
tabindex="0"
|
||||
type="button"
|
||||
(click)="onClose()"
|
||||
class="btn-close"
|
||||
aria-label="Close"
|
||||
></button>
|
||||
</div>
|
||||
<form #appointmentForm="ngForm" (ngSubmit)="saveAppointment(appointmentForm)">
|
||||
<div class="p-fluid grid justify-content-center">
|
||||
<div class="field col-md-5">
|
||||
<label for="fname">First Name <span class="text-danger">*</span></label>
|
||||
<span class="p-input-icon-left p-input-icon-right">
|
||||
<i class="pi pi-user"></i>
|
||||
<input
|
||||
autofocus
|
||||
pInputText
|
||||
id="fname"
|
||||
name="fname"
|
||||
[(ngModel)]="appointment.firstName"
|
||||
#fnameCtrl="ngModel"
|
||||
required
|
||||
minlength="2"
|
||||
maxlength="30"
|
||||
[ngClass]="{
|
||||
'is-valid': fnameCtrl.valid && fnameCtrl.touched,
|
||||
'is-invalid': fnameCtrl.invalid && fnameCtrl.touched
|
||||
}"
|
||||
/>
|
||||
<i *ngIf="fnameCtrl.valid && fnameCtrl.touched" class="pi pi-check text-success"></i>
|
||||
<i *ngIf="fnameCtrl.invalid && fnameCtrl.touched" class="pi pi-times text-danger"></i>
|
||||
</span>
|
||||
<small class="text-danger" *ngIf="fnameCtrl.invalid && fnameCtrl.touched">
|
||||
<span *ngIf="fnameCtrl.errors?.required">First Name is required.</span>
|
||||
<span *ngIf="fnameCtrl.errors?.minlength">Minimum 2 characters required.</span>
|
||||
<span *ngIf="fnameCtrl.errors?.maxlength">Maximum 30 characters allowed.</span>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="lname">Last Name <span class="text-danger">*</span></label>
|
||||
<span class="p-input-icon-left p-input-icon-right">
|
||||
<i class="pi pi-user"></i>
|
||||
<input
|
||||
pInputText
|
||||
id="lname"
|
||||
name="lname"
|
||||
[(ngModel)]="appointment.lastName"
|
||||
#lnameCtrl="ngModel"
|
||||
required
|
||||
minlength="2"
|
||||
maxlength="30"
|
||||
[ngClass]="{
|
||||
'is-valid': lnameCtrl.valid && lnameCtrl.touched,
|
||||
'is-invalid': lnameCtrl.invalid && lnameCtrl.touched
|
||||
}"
|
||||
/>
|
||||
<i *ngIf="lnameCtrl.valid && lnameCtrl.touched" class="pi pi-check text-success"></i>
|
||||
<i *ngIf="lnameCtrl.invalid && lnameCtrl.touched" class="pi pi-times text-danger"></i>
|
||||
</span>
|
||||
<small class="text-danger" *ngIf="lnameCtrl.invalid && lnameCtrl.touched">
|
||||
<span *ngIf="lnameCtrl.errors?.required">Last Name is required.</span>
|
||||
<span *ngIf="lnameCtrl.errors?.minlength">Minimum 2 characters required.</span>
|
||||
<span *ngIf="lnameCtrl.errors?.maxlength">Maximum 30 characters allowed.</span>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label>Gender <span class="text-danger">*</span></label>
|
||||
<div class="flex align-items-center p-input-icon-right">
|
||||
<p-radioButton
|
||||
name="gender"
|
||||
value="1"
|
||||
[(ngModel)]="appointment.gender"
|
||||
inputId="male"
|
||||
#genderCtrl="ngModel"
|
||||
required
|
||||
></p-radioButton>
|
||||
<label for="male" class="ml-2 mr-3">Male</label>
|
||||
|
||||
<p-radioButton
|
||||
name="gender"
|
||||
value="2"
|
||||
[(ngModel)]="appointment.gender"
|
||||
inputId="female"
|
||||
required
|
||||
></p-radioButton>
|
||||
<label for="female" class="ml-2">Female</label>
|
||||
|
||||
<i
|
||||
*ngIf="genderCtrl.valid && genderCtrl.touched"
|
||||
class="pi pi-check text-success ml-2"
|
||||
></i>
|
||||
<i
|
||||
*ngIf="genderCtrl.invalid && genderCtrl.touched"
|
||||
class="pi pi-times text-danger ml-2"
|
||||
></i>
|
||||
</div>
|
||||
<small class="text-danger d-block" *ngIf="genderCtrl.invalid && genderCtrl.touched">
|
||||
Please select a gender.
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="mobile">Mobile No <span class="text-danger">*</span></label>
|
||||
<span class="p-input-icon-left p-input-icon-right">
|
||||
<i class="pi pi-phone"></i>
|
||||
<input
|
||||
pInputText
|
||||
id="mobile"
|
||||
name="mobile"
|
||||
[(ngModel)]="appointment.mobile"
|
||||
#mobileCtrl="ngModel"
|
||||
required
|
||||
pattern="^[0-9]{10}$"
|
||||
[ngClass]="{
|
||||
'is-valid': mobileCtrl.valid && mobileCtrl.touched,
|
||||
'is-invalid': mobileCtrl.invalid && mobileCtrl.touched
|
||||
}"
|
||||
/>
|
||||
<i
|
||||
*ngIf="mobileCtrl.valid && mobileCtrl.touched"
|
||||
class="pi pi-check text-success"
|
||||
></i>
|
||||
<i
|
||||
*ngIf="mobileCtrl.invalid && mobileCtrl.touched"
|
||||
class="pi pi-times text-danger"
|
||||
></i>
|
||||
</span>
|
||||
<small class="text-danger d-block" *ngIf="mobileCtrl.invalid && mobileCtrl.touched">
|
||||
<span *ngIf="mobileCtrl.errors?.required">Mobile number is required.</span>
|
||||
<span *ngIf="mobileCtrl.errors?.pattern">Enter a valid 10-digit mobile number.</span>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-11">
|
||||
<label for="address">Address <span class="text-danger">*</span></label>
|
||||
<span class="p-input-icon-left p-input-icon-right">
|
||||
<i class="pi pi-map-marker"></i>
|
||||
<input
|
||||
pInputText
|
||||
id="address"
|
||||
name="address"
|
||||
[(ngModel)]="appointment.address"
|
||||
#addressCtrl="ngModel"
|
||||
required
|
||||
minlength="5"
|
||||
maxlength="100"
|
||||
[ngClass]="{
|
||||
'is-valid': addressCtrl.valid && addressCtrl.touched,
|
||||
'is-invalid': addressCtrl.invalid && addressCtrl.touched
|
||||
}"
|
||||
/>
|
||||
<i
|
||||
*ngIf="addressCtrl.valid && addressCtrl.touched"
|
||||
class="pi pi-check text-success"
|
||||
></i>
|
||||
<i
|
||||
*ngIf="addressCtrl.invalid && addressCtrl.touched"
|
||||
class="pi pi-times text-danger"
|
||||
></i>
|
||||
</span>
|
||||
<small class="text-danger d-block" *ngIf="addressCtrl.invalid && addressCtrl.touched">
|
||||
<span *ngIf="addressCtrl.errors?.required">Address is required.</span>
|
||||
<span *ngIf="addressCtrl.errors?.minlength">Minimum 5 characters required.</span>
|
||||
<span *ngIf="addressCtrl.errors?.maxlength">Maximum 100 characters allowed.</span>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="email">Email ID <span class="text-danger">*</span></label>
|
||||
<span class="p-input-icon-left p-input-icon-right">
|
||||
<i class="pi pi-envelope"></i>
|
||||
<input
|
||||
pInputText
|
||||
id="email"
|
||||
name="email"
|
||||
[(ngModel)]="appointment.email"
|
||||
#emailCtrl="ngModel"
|
||||
required
|
||||
email
|
||||
[ngClass]="{
|
||||
'is-valid': emailCtrl.valid && emailCtrl.touched,
|
||||
'is-invalid': emailCtrl.invalid && emailCtrl.touched
|
||||
}"
|
||||
/>
|
||||
<i *ngIf="emailCtrl.valid && emailCtrl.touched" class="pi pi-check text-success"></i>
|
||||
<i *ngIf="emailCtrl.invalid && emailCtrl.touched" class="pi pi-times text-danger"></i>
|
||||
</span>
|
||||
<small class="text-danger d-block" *ngIf="emailCtrl.invalid && emailCtrl.touched">
|
||||
<span *ngIf="emailCtrl.errors?.required">Email address is required.</span>
|
||||
<span *ngIf="emailCtrl.errors?.email">Enter a valid email address.</span>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="dob">Date of Birth <span class="text-danger">*</span></label>
|
||||
<p-calendar
|
||||
id="dob"
|
||||
required
|
||||
name="dob"
|
||||
[(ngModel)]="Dateofbirth"
|
||||
[showIcon]="true"
|
||||
required
|
||||
></p-calendar>
|
||||
<small
|
||||
class="p-error"
|
||||
*ngIf="appointmentForm.controls.dob?.invalid && appointmentForm.controls.dob?.touched"
|
||||
>DOB Required</small
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="doctor">Consulting Doctor <span class="text-danger">*</span></label>
|
||||
<p-dropdown
|
||||
id="doctor"
|
||||
name="doctor"
|
||||
[(ngModel)]="appointment.doctorId"
|
||||
[options]="doctorOptions"
|
||||
placeholder="Select Doctor"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
required
|
||||
></p-dropdown>
|
||||
</div>
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="date">Date of Appointment <span class="text-danger">*</span></label>
|
||||
<p-calendar
|
||||
id="date"
|
||||
name="date"
|
||||
[(ngModel)]="AppointmentDate"
|
||||
[showIcon]="true"
|
||||
required
|
||||
></p-calendar>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="time">Time Of Appointment <span class="text-danger">*</span></label>
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-clock"></i>
|
||||
<input
|
||||
pInputText
|
||||
id="time"
|
||||
name="time"
|
||||
type="time"
|
||||
[(ngModel)]="appointment.timeOfAppointment"
|
||||
required
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="injury">Injury/Condition</label>
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-exclamation-triangle"></i>
|
||||
<input
|
||||
pInputText
|
||||
id="injury"
|
||||
name="injury"
|
||||
[(ngModel)]="appointment.injuryORContion"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="insurance">Insurance Provider</label>
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-credit-card"></i>
|
||||
<input
|
||||
pInputText
|
||||
id="insurance"
|
||||
name="insuranceProvider"
|
||||
[(ngModel)]="appointment.insuranceProvider"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="status">Appointment Status</label>
|
||||
<p-dropdown
|
||||
id="status"
|
||||
name="status"
|
||||
[(ngModel)]="appointment.appointmentStatus"
|
||||
[options]="appointmentStatuses"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
placeholder="Select Status"
|
||||
></p-dropdown>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="visitType">Visit Type</label>
|
||||
<p-dropdown
|
||||
id="visitType"
|
||||
name="visitType"
|
||||
[(ngModel)]="appointment.visitType"
|
||||
[options]="visitTypes"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
placeholder="Select Visit Type"
|
||||
></p-dropdown>
|
||||
</div>
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="paymentStatus">Payment Status</label>
|
||||
<p-dropdown
|
||||
id="paymentStatus"
|
||||
name="paymentStatus"
|
||||
[(ngModel)]="appointment.paymentStatus"
|
||||
[options]="paymentStatuses"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
placeholder="Select Payment Status"
|
||||
></p-dropdown>
|
||||
</div>
|
||||
|
||||
<div class="field col-11">
|
||||
<label for="notes">Notes</label>
|
||||
<textarea
|
||||
id="notes"
|
||||
name="notes"
|
||||
[(ngModel)]="appointment.note"
|
||||
rows="5"
|
||||
cols="30"
|
||||
pInputTextarea
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<div class="field col-11 flex justify-content-end">
|
||||
<button
|
||||
pButton
|
||||
type="submit"
|
||||
label="Save"
|
||||
class="p-button-success"
|
||||
[disabled]="appointmentForm.invalid"
|
||||
></button>
|
||||
<button
|
||||
pButton
|
||||
type="button"
|
||||
label="Cancel"
|
||||
class="p-button-secondary ml-2"
|
||||
(click)="onClose()"
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,23 @@
|
||||
.hide_body{
|
||||
scrollbar-width: auto !important;
|
||||
min-height: 150px;
|
||||
max-height: calc(100vh - 13rem);
|
||||
overflow-y: auto;
|
||||
}
|
||||
.is-valid {
|
||||
border-color: green !important;
|
||||
}
|
||||
.is-invalid {
|
||||
border-color: red !important;
|
||||
}
|
||||
|
||||
/* Adjust the z-index of the calendar dropdown */
|
||||
.p-calendar .p-datepicker {
|
||||
z-index: 1050 !important; /* Make sure it's above other elements */
|
||||
}
|
||||
|
||||
/* You can also adjust modal z-index if necessary */
|
||||
.modal {
|
||||
z-index: 1040; /* Set lower z-index to ensure modal is behind the calendar */
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AppointmentDialogComponent } from './appointment-dialog.component';
|
||||
|
||||
describe('AppointmentDialogComponent', () => {
|
||||
let component: AppointmentDialogComponent;
|
||||
let fixture: ComponentFixture<AppointmentDialogComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [AppointmentDialogComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(AppointmentDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,215 @@
|
||||
import { ConfirmationService, ToasterService } from '@abp/ng.theme.shared';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnInit,
|
||||
Output,
|
||||
SimpleChanges,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { FormsModule, NgForm } from '@angular/forms';
|
||||
import { CreateOrUpdateAppointmentDto } from '@proxy/appoinments/dto';
|
||||
import { Gender, appointmentStatus, visitType, paymentStatus } from '@proxy/global-enum';
|
||||
import { DoctorService } from '@proxy/doctors';
|
||||
import { AppointmentService } from '@proxy/appointments';
|
||||
import { ButtonModule } from 'primeng/button';
|
||||
import { CalendarModule } from 'primeng/calendar';
|
||||
import { ChipModule } from 'primeng/chip';
|
||||
import { DialogModule } from 'primeng/dialog';
|
||||
import { DropdownModule } from 'primeng/dropdown';
|
||||
import { InputTextModule } from 'primeng/inputtext';
|
||||
import { InputTextareaModule } from 'primeng/inputtextarea';
|
||||
import { RadioButtonModule } from 'primeng/radiobutton';
|
||||
import { TableModule } from 'primeng/table';
|
||||
import { ViewAppointmentRoutingModule } from '../view-appointment/view-appointment-routing.module';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-appointment-dialog',
|
||||
standalone: true,
|
||||
imports: [
|
||||
ViewAppointmentRoutingModule,
|
||||
TableModule,
|
||||
DialogModule,
|
||||
FormsModule,
|
||||
TableModule,
|
||||
ButtonModule,
|
||||
DialogModule,
|
||||
InputTextModule,
|
||||
CalendarModule,
|
||||
DropdownModule,
|
||||
RadioButtonModule,
|
||||
InputTextareaModule,
|
||||
ChipModule,
|
||||
CommonModule,
|
||||
],
|
||||
templateUrl: './appointment-dialog.component.html',
|
||||
styleUrl: './appointment-dialog.component.scss',
|
||||
})
|
||||
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() selectedDate: string;
|
||||
appointmentsForDate: any[] = [];
|
||||
|
||||
loading: boolean = false;
|
||||
AppointmentDialogTitle: string = '';
|
||||
AppointmentDialog: boolean = false;
|
||||
genders = Gender;
|
||||
Dateofbirth: Date = new Date();
|
||||
AppointmentDate: Date = new Date();
|
||||
doctors = [];
|
||||
doctorOptions = [];
|
||||
constructor(
|
||||
private DoctorService: DoctorService,
|
||||
private AppointmentService: AppointmentService,
|
||||
private http: HttpClient,
|
||||
private confirmation: ConfirmationService,
|
||||
private toaster: ToasterService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
debugger;
|
||||
this.getdoctorlist();
|
||||
if (!this.isEditMode) {
|
||||
this.appointment = {
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
email: '',
|
||||
gender: Gender.Male,
|
||||
dateOfAppointment: '',
|
||||
dob: '',
|
||||
timeOfAppointment: '',
|
||||
mobile: '',
|
||||
injuryORContion: '',
|
||||
note: '',
|
||||
doctorId: '',
|
||||
address: '',
|
||||
appointmentStatus: null,
|
||||
visitType: null,
|
||||
paymentStatus: null,
|
||||
insuranceProvider: '',
|
||||
};
|
||||
}
|
||||
}
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes['appointmentId'] && this.appointmentId) {
|
||||
// When the appointment ID changes, fetch the appointment details
|
||||
this.fetchAppointmentData();
|
||||
}
|
||||
if (changes['selectedDate'] && this.selectedDate) {
|
||||
this.fetchAppointmentsForDate();
|
||||
}
|
||||
}
|
||||
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: '',
|
||||
lastName: '',
|
||||
email: '',
|
||||
gender: Gender.Male,
|
||||
mobile: '',
|
||||
address: '',
|
||||
dob: '',
|
||||
doctorId: '',
|
||||
dateOfAppointment: '',
|
||||
timeOfAppointment: '',
|
||||
injuryORContion: '',
|
||||
note: '',
|
||||
appointmentStatus: appointmentStatus.Scheduled,
|
||||
visitType: visitType.NewPatient,
|
||||
paymentStatus: paymentStatus.Unpaid,
|
||||
insuranceProvider: '',
|
||||
};
|
||||
|
||||
saveAppointment(form: NgForm) {
|
||||
debugger;
|
||||
if (form.invalid) {
|
||||
Object.values(form.controls).forEach(control => control.markAsTouched());
|
||||
return;
|
||||
}
|
||||
this.appointment.dob = this.Dateofbirth.toDateString();
|
||||
this.appointment.dateOfAppointment = this.AppointmentDate.toDateString();
|
||||
if (this.isEditMode) {
|
||||
this.AppointmentService.updateAppointment(this.appointment).subscribe(
|
||||
() => {
|
||||
this.toaster.success('Appointment updated successfully', 'Success');
|
||||
this.AppointmentDialog = false;
|
||||
|
||||
this.onClose();
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
this.toaster.error(error, 'Error');
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.AppointmentService.createAppointment(this.appointment).subscribe(
|
||||
() => {
|
||||
this.toaster.success('Appointment created successfully', 'Success');
|
||||
this.AppointmentDialog = false;
|
||||
|
||||
this.onClose();
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
this.toaster.error(error, 'Error');
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
getdoctorlist() {
|
||||
this.DoctorService.get().subscribe(result => {
|
||||
this.doctors = result;
|
||||
this.doctorOptions = this.doctors.map(doctor => ({
|
||||
label: `Dr. ${doctor.firstName} ${doctor.lastName}`,
|
||||
value: doctor.id,
|
||||
}));
|
||||
});
|
||||
}
|
||||
appointmentStatuses = Object.keys(appointmentStatus)
|
||||
.filter(key => !isNaN(Number(key)))
|
||||
.map(key => ({
|
||||
label: appointmentStatus[key as unknown as keyof typeof appointmentStatus],
|
||||
value: Number(key),
|
||||
}));
|
||||
visitTypes = Object.keys(visitType)
|
||||
.filter(key => !isNaN(Number(key)))
|
||||
.map(key => ({
|
||||
label: visitType[key as unknown as keyof typeof visitType],
|
||||
value: Number(key),
|
||||
}));
|
||||
paymentStatuses = Object.keys(paymentStatus)
|
||||
.filter(key => !isNaN(Number(key)))
|
||||
.map(key => ({
|
||||
label: paymentStatus[key as unknown as keyof typeof paymentStatus],
|
||||
value: Number(key),
|
||||
}));
|
||||
|
||||
onClose() {
|
||||
debugger;
|
||||
this.AppointmentDialog = false;
|
||||
|
||||
this.close.emit(); // Emit close event
|
||||
}
|
||||
}
|
25
angular/src/app/appointment/appointment-routing.module.ts
Normal file
25
angular/src/app/appointment/appointment-routing.module.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
children: [
|
||||
{
|
||||
path: 'appointment-calendar',
|
||||
loadChildren: () => import('./appointment-calendar/appointment-calendar.module').then(m => m.AppointmentCalendarModule)
|
||||
},
|
||||
{
|
||||
path: 'view-appointment',
|
||||
loadChildren: () => import('./view-appointment/view-appointment.module').then(m => m.ViewAppointmentModule)
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppointmentRoutingModule { }
|
16
angular/src/app/appointment/appointment.module.ts
Normal file
16
angular/src/app/appointment/appointment.module.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { AppointmentRoutingModule } from './appointment-routing.module';
|
||||
import { AppointmentDialogComponent } from './appointment-dialog/appointment-dialog.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [
|
||||
CommonModule,
|
||||
AppointmentRoutingModule,
|
||||
AppointmentDialogComponent
|
||||
]
|
||||
})
|
||||
export class AppointmentModule { }
|
@ -1,11 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { BookAppointmentComponent } from './book-appointment.component';
|
||||
|
||||
const routes: Routes = [{ path: '', component: BookAppointmentComponent }];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class BookAppointmentRoutingModule { }
|
@ -1 +0,0 @@
|
||||
<p>book-appointment works!</p>
|
@ -1,23 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { BookAppointmentComponent } from './book-appointment.component';
|
||||
|
||||
describe('BookAppointmentComponent', () => {
|
||||
let component: BookAppointmentComponent;
|
||||
let fixture: ComponentFixture<BookAppointmentComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [BookAppointmentComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(BookAppointmentComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -1,10 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-book-appointment',
|
||||
templateUrl: './book-appointment.component.html',
|
||||
styleUrl: './book-appointment.component.scss'
|
||||
})
|
||||
export class BookAppointmentComponent {
|
||||
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { BookAppointmentRoutingModule } from './book-appointment-routing.module';
|
||||
import { BookAppointmentComponent } from './book-appointment.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
BookAppointmentComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
BookAppointmentRoutingModule
|
||||
]
|
||||
})
|
||||
export class BookAppointmentModule { }
|
@ -1,11 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { EditAppointmentComponent } from './edit-appointment.component';
|
||||
|
||||
const routes: Routes = [{ path: '', component: EditAppointmentComponent }];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class EditAppointmentRoutingModule { }
|
@ -1 +0,0 @@
|
||||
<p>edit-appointment works!</p>
|
@ -1,23 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { EditAppointmentComponent } from './edit-appointment.component';
|
||||
|
||||
describe('EditAppointmentComponent', () => {
|
||||
let component: EditAppointmentComponent;
|
||||
let fixture: ComponentFixture<EditAppointmentComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [EditAppointmentComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(EditAppointmentComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -1,10 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-edit-appointment',
|
||||
templateUrl: './edit-appointment.component.html',
|
||||
styleUrl: './edit-appointment.component.scss'
|
||||
})
|
||||
export class EditAppointmentComponent {
|
||||
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { EditAppointmentRoutingModule } from './edit-appointment-routing.module';
|
||||
import { EditAppointmentComponent } from './edit-appointment.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
EditAppointmentComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
EditAppointmentRoutingModule
|
||||
]
|
||||
})
|
||||
export class EditAppointmentModule { }
|
@ -17,21 +17,21 @@
|
||||
<ng-template pTemplate="caption">
|
||||
<div class="flex align-items-center justify-content-between mb-3 gap-3">
|
||||
<!-- Left: Title -->
|
||||
<h2 class="m-0">Appointment List</h2>
|
||||
<h4 class="m-0">Appointment List</h4>
|
||||
|
||||
<!-- Center: Search Bar with Icon Inside -->
|
||||
<div class="flex-grow-1 flex justify-content-center">
|
||||
<span class="p-input-icon-left w-100">
|
||||
<i class="pi pi-search"></i>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="pi pi-search"></i></span>
|
||||
<input
|
||||
pInputText
|
||||
type="text"
|
||||
class="form-control"
|
||||
(input)="dt2.filterGlobal($event.target.value, 'contains')"
|
||||
[(ngModel)]="globalFilter"
|
||||
placeholder="Search Appointments"
|
||||
(input)="dt2.filterGlobal(globalFilter, 'contains')"
|
||||
class="w-full"
|
||||
placeholder="Search keyword"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
@ -51,7 +51,11 @@
|
||||
>
|
||||
<i class="pi pi-plus-circle"></i>
|
||||
</button>
|
||||
<button pButton class="p-button-rounded p-button-warning ml-2" (click)="exportAppointments()">
|
||||
<button
|
||||
pButton
|
||||
class="p-button-rounded p-button-warning ml-2"
|
||||
(click)="exportAppointments()"
|
||||
>
|
||||
<i class="pi pi-download"></i>
|
||||
</button>
|
||||
</div>
|
||||
@ -67,7 +71,9 @@
|
||||
<th pSortableColumn="timeOfAppointment">Time<p-sortIcon field="timeOfAppointment" /></th>
|
||||
<th>Mobile No</th>
|
||||
<th>Email</th>
|
||||
<th pSortableColumn="appointmentStatus">Appointment Status<p-sortIcon field="appointmentStatus" /></th>
|
||||
<th pSortableColumn="appointmentStatus">
|
||||
Appointment Status<p-sortIcon field="appointmentStatus" />
|
||||
</th>
|
||||
<th pSortableColumn="visitType">Visit Type<p-sortIcon field="visitType" /></th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
@ -78,296 +84,45 @@
|
||||
<td>{{ appointment.firstName }} {{ appointment.lastName }}</td>
|
||||
<td>{{ appointment.doctor }}</td>
|
||||
<td>
|
||||
<p-chip
|
||||
[severity]="appointment.gender === 1 ? 'info' : 'danger'"
|
||||
[styleClass]="'px-2 py-1 text-sm font-medium'"
|
||||
>
|
||||
|
||||
<span class="badge" [ngClass]="appointment.gender === 1 ? 'bg-primary' : 'bg-pink'">
|
||||
{{ getGenderLabel(appointment.gender) }}
|
||||
</p-chip>
|
||||
|
||||
</span>
|
||||
</td>
|
||||
<td>{{ appointment.dateOfAppointment | date }}</td>
|
||||
<td>{{ appointment.timeOfAppointment }}</td>
|
||||
<td>{{ appointment.mobile }}</td>
|
||||
<td>{{ appointment.email }}</td>
|
||||
<td>
|
||||
<p-chip
|
||||
[severity]="appointment.appointmentStatus === 1 ? 'info' : 'danger'"
|
||||
[styleClass]="'px-2 py-1 text-sm font-medium'"
|
||||
<span
|
||||
class="badge"
|
||||
[ngClass]="
|
||||
appointment.appointmentStatus === 1
|
||||
? 'bg-success'
|
||||
: appointment.appointmentStatus === 2
|
||||
? 'bg-primary'
|
||||
: 'bg-danger'
|
||||
"
|
||||
>
|
||||
|
||||
{{ getStatusLabel(appointment.appointmentStatus) }}
|
||||
</p-chip>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<p-chip
|
||||
[severity]="appointment.visitType === 1 ? 'info' : 'danger'"
|
||||
[styleClass]="'px-2 py-1 text-sm font-medium'"
|
||||
>
|
||||
|
||||
<span class="badge" [ngClass]="appointment.visitType === 1 ? 'bg-success' : 'bg-danger'">
|
||||
{{ getVisitTypeLabel(appointment.visitType) }}
|
||||
</p-chip>
|
||||
</span>
|
||||
</td>
|
||||
<td class="d-flex">
|
||||
<button class="btn btn-warning btn-sm ml-1" (click)="editAppointment(appointment)">
|
||||
<i class="pi pi-pencil"></i>
|
||||
</button>
|
||||
<button class="btn btn-danger btn-sm ml-1"
|
||||
(click)="deleteAppointment(appointment.id)"><i class="pi pi-trash"></i></button>
|
||||
<button class="btn btn-danger btn-sm ml-1" (click)="deleteAppointment(appointment.id)">
|
||||
<i class="pi pi-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
</p-table>
|
||||
</div>
|
||||
|
||||
<p-dialog
|
||||
header="{{ isEditMode ? 'Edit Appointment' : 'New Appointment' }}"
|
||||
[(visible)]="appointmentDialog"
|
||||
[modal]="true"
|
||||
[closable]="true"
|
||||
[style]="{ width: '80%' }"
|
||||
>
|
||||
<form #appointmentForm="ngForm" (ngSubmit)="saveAppointment(appointmentForm)">
|
||||
<div class="p-fluid grid justify-content-center">
|
||||
<div class="field col-md-5">
|
||||
<label for="fname">First Name <span class="text-danger">*</span></label>
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-user"></i>
|
||||
<input pInputText id="fname" name="fname" [(ngModel)]="appointment.firstName" required />
|
||||
</span>
|
||||
</div>
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="lname">Last Name <span class="text-danger">*</span></label>
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-user"></i>
|
||||
<input pInputText id="lname" name="lname" [(ngModel)]="appointment.lastName" required />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label>Gender <span class="text-danger">*</span></label>
|
||||
<div class="flex align-items-center">
|
||||
<p-radioButton
|
||||
name="gender"
|
||||
value="1"
|
||||
[(ngModel)]="appointment.gender"
|
||||
inputId="male"
|
||||
required
|
||||
></p-radioButton>
|
||||
<label for="male" class="ml-2 mr-3">Male</label>
|
||||
<p-radioButton
|
||||
name="gender"
|
||||
value="2"
|
||||
[(ngModel)]="appointment.gender"
|
||||
inputId="female"
|
||||
required
|
||||
></p-radioButton>
|
||||
<label for="female" class="ml-2">Female</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="mobile">Mobile No <span class="text-danger">*</span></label>
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-phone"></i>
|
||||
<input pInputText id="mobile" name="mobile" [(ngModel)]="appointment.mobile" required />
|
||||
</span>
|
||||
<small
|
||||
class="p-error"
|
||||
*ngIf="
|
||||
appointmentForm.controls.mobile?.invalid && appointmentForm.controls.mobile?.touched
|
||||
"
|
||||
>Mobile number Required</small
|
||||
>
|
||||
</div>
|
||||
<div class="field col-md-11">
|
||||
<label for="mobile">Address <span class="text-danger">*</span></label>
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-map-marker"></i>
|
||||
<input
|
||||
pInputText
|
||||
id="Address"
|
||||
name="Address"
|
||||
[(ngModel)]="appointment.address"
|
||||
required
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="email">Email ID <span class="text-danger">*</span></label>
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-envelope"></i>
|
||||
<input pInputText id="email" name="email" [(ngModel)]="appointment.email" required />
|
||||
</span>
|
||||
<small
|
||||
class="p-error"
|
||||
*ngIf="appointmentForm.controls.email?.invalid && appointmentForm.controls.email?.touched"
|
||||
>Email address Required</small
|
||||
>
|
||||
</div>
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="dob">Date of Birth <span class="text-danger">*</span></label>
|
||||
<p-calendar
|
||||
id="dob"
|
||||
required
|
||||
name="dob"
|
||||
[(ngModel)]="Dateofbirth"
|
||||
[showIcon]="true"
|
||||
appendTo="body"
|
||||
required
|
||||
></p-calendar>
|
||||
<small
|
||||
class="p-error"
|
||||
*ngIf="appointmentForm.controls.dob?.invalid && appointmentForm.controls.dob?.touched"
|
||||
>DOB Required</small
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="doctor">Consulting Doctor <span class="text-danger">*</span></label>
|
||||
<p-dropdown
|
||||
id="doctor"
|
||||
name="doctor"
|
||||
[(ngModel)]="appointment.doctorId"
|
||||
[options]="doctorOptions"
|
||||
placeholder="Select Doctor"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
required
|
||||
></p-dropdown>
|
||||
</div>
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="date">Date of Appointment <span class="text-danger">*</span></label>
|
||||
<p-calendar
|
||||
id="date"
|
||||
name="date"
|
||||
[(ngModel)]="AppointmentDate"
|
||||
[showIcon]="true"
|
||||
appendTo="body"
|
||||
required
|
||||
></p-calendar>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="time">Time Of Appointment <span class="text-danger">*</span></label>
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-clock"></i>
|
||||
<input
|
||||
pInputText
|
||||
id="time"
|
||||
name="time"
|
||||
type="time"
|
||||
[(ngModel)]="appointment.timeOfAppointment"
|
||||
required
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="injury">Injury/Condition</label>
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-exclamation-triangle"></i>
|
||||
<input pInputText id="injury" name="injury" [(ngModel)]="appointment.injuryORContion" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="insurance">Insurance Provider</label>
|
||||
<span class="p-input-icon-left">
|
||||
<i class="pi pi-credit-card"></i>
|
||||
<input
|
||||
pInputText
|
||||
id="insurance"
|
||||
name="insuranceProvider"
|
||||
[(ngModel)]="appointment.insuranceProvider"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="status">Appointment Status</label>
|
||||
<p-dropdown
|
||||
id="status"
|
||||
name="status"
|
||||
[(ngModel)]="appointment.appointmentStatus"
|
||||
[options]="appointmentStatuses"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
placeholder="Select Status"
|
||||
|
||||
></p-dropdown>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="visitType">Visit Type</label>
|
||||
<p-dropdown
|
||||
id="visitType"
|
||||
name="visitType"
|
||||
[(ngModel)]="appointment.visitType"
|
||||
[options]="visitTypes"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
placeholder="Select Visit Type"
|
||||
|
||||
></p-dropdown>
|
||||
</div>
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-5">
|
||||
<label for="paymentStatus">Payment Status</label>
|
||||
<p-dropdown
|
||||
id="paymentStatus"
|
||||
name="paymentStatus"
|
||||
[(ngModel)]="appointment.paymentStatus"
|
||||
[options]="paymentStatuses"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
placeholder="Select Payment Status"
|
||||
|
||||
></p-dropdown>
|
||||
</div>
|
||||
|
||||
<!-- Notes (Full Width) -->
|
||||
<div class="field col-11">
|
||||
<label for="notes">Notes</label>
|
||||
<textarea
|
||||
id="notes"
|
||||
name="notes"
|
||||
[(ngModel)]="appointment.note"
|
||||
rows="5"
|
||||
cols="30"
|
||||
pInputTextarea
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<div class="field col-11 flex justify-content-end">
|
||||
<button
|
||||
pButton
|
||||
type="submit"
|
||||
label="Save"
|
||||
class="p-button-success"
|
||||
[disabled]="appointmentForm.invalid"
|
||||
></button>
|
||||
<button
|
||||
pButton
|
||||
type="button"
|
||||
label="Cancel"
|
||||
class="p-button-secondary ml-2"
|
||||
(click)="closeDialog()"
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</p-dialog>
|
||||
<app-appointment-dialog [appointmentId]="appointmentIdToEdit"[isEditMode]="isEditMode"
|
||||
[visible]="isModalVisible"*ngIf="isModalVisible" [name]="'Appointment'" (close)="closeDialog()"></app-appointment-dialog>
|
||||
|
@ -1,3 +1,11 @@
|
||||
.is-valid {
|
||||
border-color: green !important;
|
||||
}
|
||||
.is-invalid {
|
||||
border-color: red !important;
|
||||
}
|
||||
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@ -13,3 +21,24 @@
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.male {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.female {
|
||||
background-color: purple;
|
||||
}
|
||||
|
||||
.pdf-icon {
|
||||
color: red;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.bg-pink {
|
||||
background-color: #ff4081 !important;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.gap-1 {
|
||||
gap: 5px;
|
||||
}
|
||||
|
@ -15,14 +15,15 @@ import { appointmentStatus, Gender, paymentStatus, visitType } from '@proxy/glob
|
||||
})
|
||||
export class ViewAppointmentComponent {
|
||||
totalRecords: number = 0;
|
||||
appointmentIdToEdit: string;
|
||||
|
||||
AppointmentDialogTitle: string = '';
|
||||
AppointmentDialog: boolean = false;
|
||||
patients: [];
|
||||
appointmentDialog = false;
|
||||
genders = Gender;
|
||||
Dateofbirth: Date = new Date();
|
||||
AppointmentDate: Date = new Date();
|
||||
|
||||
isModalVisible:boolean=false;
|
||||
appointmentStatuses = Object.keys(appointmentStatus)
|
||||
.filter(key => !isNaN(Number(key)))
|
||||
.map(key => ({
|
||||
@ -122,26 +123,27 @@ 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: '',
|
||||
};
|
||||
//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: '',
|
||||
// };
|
||||
}
|
||||
|
||||
|
||||
@ -174,14 +176,17 @@ export class ViewAppointmentComponent {
|
||||
editAppointment(appointment: any) {
|
||||
debugger;
|
||||
this.isEditMode = true;
|
||||
this.appointmentDialog = true;
|
||||
this.appointmentIdToEdit = appointment.id;
|
||||
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);
|
||||
});
|
||||
// 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) {
|
||||
@ -200,58 +205,17 @@ export class ViewAppointmentComponent {
|
||||
}
|
||||
});
|
||||
}
|
||||
saveAppointment(form: NgForm) {
|
||||
debugger;
|
||||
console.log(form.controls);
|
||||
if (form.invalid) {
|
||||
Object.values(form.controls).forEach(control => control.markAsTouched());
|
||||
return;
|
||||
}
|
||||
this.appointment.dob = this.Dateofbirth.toDateString();
|
||||
this.appointment.dateOfAppointment = this.AppointmentDate.toDateString();
|
||||
if (this.isEditMode) {
|
||||
this.AppointmentService.updateAppointment(this.appointment).subscribe(
|
||||
() => {
|
||||
this.toaster.success('Appointment updated successfully', 'Success');
|
||||
this.AppointmentDialog = false;
|
||||
this.loadappointments({
|
||||
first: 0,
|
||||
rows: 10,
|
||||
sortField: 'id',
|
||||
sortOrder: 1,
|
||||
globalFilter: null,
|
||||
});
|
||||
this.closeDialog();
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
this.toaster.error(error, 'Error');
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.AppointmentService.createAppointment(this.appointment).subscribe(
|
||||
() => {
|
||||
this.toaster.success('Appointment created successfully', 'Success');
|
||||
this.AppointmentDialog = false;
|
||||
this.loadappointments({
|
||||
first: 0,
|
||||
rows: 10,
|
||||
sortField: 'id',
|
||||
sortOrder: 1,
|
||||
globalFilter: null,
|
||||
});
|
||||
this.closeDialog();
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
this.toaster.error(error.error.error.message, 'Error');
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
closeDialog() {
|
||||
this.appointmentDialog = false;
|
||||
debugger
|
||||
this.isModalVisible = false;
|
||||
this.loadappointments({
|
||||
first: 0,
|
||||
rows: 10,
|
||||
sortField: 'id',
|
||||
sortOrder: 1,
|
||||
globalFilter: null,
|
||||
});
|
||||
}
|
||||
getdoctorlist() {
|
||||
this.DoctorService.get().subscribe(result => {
|
||||
@ -263,4 +227,9 @@ export class ViewAppointmentComponent {
|
||||
}));
|
||||
});
|
||||
}
|
||||
saveAppointment(appointmentData: any) {
|
||||
// Save appointment logic here
|
||||
console.log('Appointment saved:', appointmentData);
|
||||
this.closeDialog(); // Close the dialog after saving
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import { RadioButtonModule } from 'primeng/radiobutton';
|
||||
import { DoctorService } from '@proxy/doctors';
|
||||
import { InputTextareaModule } from 'primeng/inputtextarea';
|
||||
import { ChipModule } from 'primeng/chip';
|
||||
import { AppointmentDialogComponent } from "../appointment-dialog/appointment-dialog.component";
|
||||
|
||||
@NgModule({
|
||||
declarations: [ViewAppointmentComponent],
|
||||
@ -31,8 +32,8 @@ import { ChipModule } from 'primeng/chip';
|
||||
DropdownModule,
|
||||
RadioButtonModule,
|
||||
InputTextareaModule,
|
||||
ChipModule
|
||||
|
||||
ChipModule,
|
||||
AppointmentDialogComponent
|
||||
],
|
||||
providers:[DoctorService]
|
||||
})
|
||||
|
@ -1462,14 +1462,36 @@
|
||||
"allowAnonymous": false,
|
||||
"implementFrom": "HospitalManagementSystem.Patients.PatientAppService"
|
||||
},
|
||||
"GetExportPatientRecordAsync": {
|
||||
"uniqueName": "GetExportPatientRecordAsync",
|
||||
"GetExportPatientRecordAsyncByPatientId": {
|
||||
"uniqueName": "GetExportPatientRecordAsyncByPatientId",
|
||||
"name": "GetExportPatientRecordAsync",
|
||||
"httpMethod": "GET",
|
||||
"url": "api/app/patient/export-patient-record",
|
||||
"url": "api/app/patient/export-patient-record/{patientId}",
|
||||
"supportedVersions": [],
|
||||
"parametersOnMethod": [],
|
||||
"parameters": [],
|
||||
"parametersOnMethod": [
|
||||
{
|
||||
"name": "patientId",
|
||||
"typeAsString": "System.Guid, System.Private.CoreLib",
|
||||
"type": "System.Guid",
|
||||
"typeSimple": "string",
|
||||
"isOptional": false,
|
||||
"defaultValue": null
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"nameOnMethod": "patientId",
|
||||
"name": "patientId",
|
||||
"jsonName": null,
|
||||
"type": "System.Guid",
|
||||
"typeSimple": "string",
|
||||
"isOptional": false,
|
||||
"defaultValue": null,
|
||||
"constraintTypes": [],
|
||||
"bindingSourceId": "Path",
|
||||
"descriptorName": ""
|
||||
}
|
||||
],
|
||||
"returnValue": {
|
||||
"type": "HospitalManagementSystem.Dto.FileDownloadDto",
|
||||
"typeSimple": "HospitalManagementSystem.Dto.FileDownloadDto"
|
||||
@ -5609,6 +5631,18 @@
|
||||
"enumValues": null,
|
||||
"genericArguments": null,
|
||||
"properties": [
|
||||
{
|
||||
"name": "Id",
|
||||
"jsonName": null,
|
||||
"type": "System.Guid",
|
||||
"typeSimple": "string",
|
||||
"isRequired": false,
|
||||
"minLength": null,
|
||||
"maxLength": null,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"regex": null
|
||||
},
|
||||
{
|
||||
"name": "FirstName",
|
||||
"jsonName": null,
|
||||
|
@ -36,20 +36,7 @@ function configureRoutes(routesService: RoutesService) {
|
||||
iconClass: 'fas fa-clock',
|
||||
order: 103,
|
||||
},
|
||||
{
|
||||
path: '/appointment/book-appointment',
|
||||
name: 'Book Appointment',
|
||||
parentName: 'Appointments',
|
||||
iconClass: 'fas fa-clock',
|
||||
order: 104,
|
||||
},
|
||||
{
|
||||
path: '/appointment/edit-appointment',
|
||||
name: 'Edit Appointment',
|
||||
parentName: 'Appointments',
|
||||
iconClass: 'fas fa-clock',
|
||||
order: 105,
|
||||
},
|
||||
|
||||
{
|
||||
path: '/patients',
|
||||
name: 'Patients',
|
||||
|
@ -34,12 +34,13 @@ namespace HospitalManagementSystem.Appointments
|
||||
private readonly IRepository<Doctor, Guid> _doctorRepository;
|
||||
private readonly IWebHostEnvironment _env;
|
||||
|
||||
public AppointmentAppService(ICurrentUser currentUser, ICurrentTenant currentTenant, IRepository<Appointment, Guid> appointmentsRepository, IRepository<Doctor, Guid> doctorRepository)
|
||||
public AppointmentAppService(ICurrentUser currentUser, ICurrentTenant currentTenant, IRepository<Appointment, Guid> appointmentsRepository, IRepository<Doctor, Guid> doctorRepository, IWebHostEnvironment env)
|
||||
{
|
||||
_currentUser = currentUser;
|
||||
_currentTenant = currentTenant;
|
||||
_appointmentsRepository = appointmentsRepository;
|
||||
_doctorRepository = doctorRepository;
|
||||
_env = env;
|
||||
}
|
||||
public async Task<string> GetAsync()
|
||||
{
|
||||
@ -163,15 +164,19 @@ namespace HospitalManagementSystem.Appointments
|
||||
|
||||
for (int i = 0; i < Appointmentrecord.Count; i++)
|
||||
{
|
||||
//worksheet.Cell(i + 2, 1).Value = Appointmentrecord[i].Patients.Name;
|
||||
//worksheet.Cell(i + 2, 2).Value = Appointmentrecord[i].Patients.Gender.ToString();
|
||||
//worksheet.Cell(i + 2, 3).Value = Appointmentrecord[i].DateOfAdmission.ToShortDateString();
|
||||
//worksheet.Cell(i + 2, 4).Value = Appointmentrecord[i].Diagnosis;
|
||||
//worksheet.Cell(i + 2, 5).Value = Appointmentrecord[i].NextFollowUp?.ToShortDateString();
|
||||
//worksheet.Cell(i + 2, 6).Value = Appointmentrecord[i].InsuranceProvider;
|
||||
//worksheet.Cell(i + 2, 7).Value = Appointmentrecord[i].InsuranceProvider;
|
||||
//worksheet.Cell(i + 2, 8).Value = Appointmentrecord[i].InsuranceProvider;
|
||||
//worksheet.Cell(i + 2, 9).Value = Appointmentrecord[i].Status.ToString();
|
||||
worksheet.Cell(i + 2, 1).Value = Appointmentrecord[i].FirstName + "" + Appointmentrecord[i].LastName;
|
||||
worksheet.Cell(i + 2, 2).Value = Appointmentrecord[i].Email;
|
||||
worksheet.Cell(i + 2, 3).Value = Appointmentrecord[i].Gender.ToString();
|
||||
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, 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();
|
||||
worksheet.Cell(i + 2, 11).Value = Appointmentrecord[i].PaymentStatus.ToString();
|
||||
worksheet.Cell(i + 2, 12).Value = Appointmentrecord[i].InsuranceProvider;
|
||||
worksheet.Cell(i + 2, 13).Value = Appointmentrecord[i].Note;
|
||||
}
|
||||
|
||||
worksheet.Columns().AdjustToContents();
|
||||
|
Loading…
x
Reference in New Issue
Block a user