Modified Doctors Module & Add Room Management component.
This commit is contained in:
parent
2b5b7be681
commit
74c18e7b07
@ -52,6 +52,10 @@ const routes: Routes = [
|
||||
path: 'doctors',
|
||||
loadChildren: () => import('./doctors/doctors.module').then(m => m.DoctorsModule),
|
||||
},
|
||||
{
|
||||
path: 'rooms',
|
||||
loadChildren: () => import('./room-management/room-management.module').then(m => m.RoomManagementModule),
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
@ -22,75 +22,371 @@
|
||||
</div>
|
||||
<form #doctorForm="ngForm" (ngSubmit)="saveDoctor(doctorForm)">
|
||||
<div class="p-fluid grid justify-content-center">
|
||||
<!-- First Name -->
|
||||
<div class="field col-md-5">
|
||||
<label for="firstName">First Name <span class="text-danger">*</span></label>
|
||||
<input pInputText id="firstName" name="firstName" [(ngModel)]="doctor.firstName" required #firstNameCtrl="ngModel"
|
||||
[ngClass]="{'is-invalid': firstNameCtrl.invalid && firstNameCtrl.touched}" />
|
||||
<small class="text-danger" *ngIf="firstNameCtrl.invalid && firstNameCtrl.touched">First Name is required.</small>
|
||||
<span class="p-input-icon-left p-input-icon-right">
|
||||
<i class="pi pi-user"></i>
|
||||
<input
|
||||
pInputText
|
||||
id="firstName"
|
||||
name="firstName"
|
||||
[(ngModel)]="doctor.firstName"
|
||||
#firstNameCtrl="ngModel"
|
||||
required
|
||||
minlength="2"
|
||||
maxlength="30"
|
||||
[ngClass]="{
|
||||
'is-valid': firstNameCtrl.valid && firstNameCtrl.touched,
|
||||
'is-invalid': firstNameCtrl.invalid && firstNameCtrl.touched
|
||||
}"
|
||||
/>
|
||||
<i
|
||||
*ngIf="firstNameCtrl.valid && firstNameCtrl.touched"
|
||||
class="pi pi-check text-success"
|
||||
></i>
|
||||
<i
|
||||
*ngIf="firstNameCtrl.invalid && firstNameCtrl.touched"
|
||||
class="pi pi-times text-danger"
|
||||
></i>
|
||||
</span>
|
||||
<small class="text-danger" *ngIf="firstNameCtrl.invalid && firstNameCtrl.touched">
|
||||
<span *ngIf="firstNameCtrl.errors?.required">First Name is required.</span>
|
||||
<span *ngIf="firstNameCtrl.errors?.minlength">Minimum 2 characters required.</span>
|
||||
<span *ngIf="firstNameCtrl.errors?.maxlength">Maximum 30 characters allowed.</span>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<!-- Last Name -->
|
||||
<div class="field col-md-5">
|
||||
<label for="lastName">Last Name <span class="text-danger">*</span></label>
|
||||
<input pInputText id="lastName" name="lastName" [(ngModel)]="doctor.lastName" required #lastNameCtrl="ngModel"
|
||||
[ngClass]="{'is-invalid': lastNameCtrl.invalid && lastNameCtrl.touched}" />
|
||||
<small class="text-danger" *ngIf="lastNameCtrl.invalid && lastNameCtrl.touched">Last Name is required.</small>
|
||||
<span class="p-input-icon-left p-input-icon-right">
|
||||
<i class="pi pi-user"></i>
|
||||
<input
|
||||
pInputText
|
||||
id="lastName"
|
||||
name="lastName"
|
||||
[(ngModel)]="doctor.lastName"
|
||||
#lastNameCtrl="ngModel"
|
||||
required
|
||||
minlength="2"
|
||||
maxlength="30"
|
||||
[ngClass]="{
|
||||
'is-valid': lastNameCtrl.valid && lastNameCtrl.touched,
|
||||
'is-invalid': lastNameCtrl.invalid && lastNameCtrl.touched
|
||||
}"
|
||||
/>
|
||||
<i
|
||||
*ngIf="lastNameCtrl.valid && lastNameCtrl.touched"
|
||||
class="pi pi-check text-success"
|
||||
></i>
|
||||
<i
|
||||
*ngIf="lastNameCtrl.invalid && lastNameCtrl.touched"
|
||||
class="pi pi-times text-danger"
|
||||
></i>
|
||||
</span>
|
||||
<small class="text-danger" *ngIf="lastNameCtrl.invalid && lastNameCtrl.touched">
|
||||
<span *ngIf="lastNameCtrl.errors?.required">Last Name is required.</span>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Mobile -->
|
||||
<div class="field col-md-5">
|
||||
<label for="mobile">Mobile <span class="text-danger">*</span></label>
|
||||
<input pInputText id="mobile" name="mobile" [(ngModel)]="doctor.mobile" required #mobileCtrl="ngModel"
|
||||
[ngClass]="{'is-invalid': mobileCtrl.invalid && mobileCtrl.touched}" />
|
||||
<small class="text-danger" *ngIf="mobileCtrl.invalid && mobileCtrl.touched">Mobile is required.</small>
|
||||
<span class="p-input-icon-left p-input-icon-right">
|
||||
<i class="pi pi-phone"></i>
|
||||
<input
|
||||
pInputText
|
||||
id="mobile"
|
||||
name="mobile"
|
||||
[(ngModel)]="doctor.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" *ngIf="mobileCtrl.invalid && mobileCtrl.touched">
|
||||
<span *ngIf="mobileCtrl.errors?.required">Mobile is required.</span>
|
||||
<span *ngIf="mobileCtrl.errors?.pattern">Enter a valid 10-digit number.</span>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<!-- Email -->
|
||||
<div class="field col-md-5">
|
||||
<label for="email">Email <span class="text-danger">*</span></label>
|
||||
<input pInputText id="email" name="email" [(ngModel)]="doctor.email" required type="email" #emailCtrl="ngModel"
|
||||
[ngClass]="{'is-invalid': emailCtrl.invalid && emailCtrl.touched}" />
|
||||
<small class="text-danger" *ngIf="emailCtrl.invalid && emailCtrl.touched">Valid Email is required.</small>
|
||||
<span class="p-input-icon-left p-input-icon-right">
|
||||
<i class="pi pi-envelope"></i>
|
||||
<input
|
||||
pInputText
|
||||
id="email"
|
||||
name="email"
|
||||
[(ngModel)]="doctor.email"
|
||||
#emailCtrl="ngModel"
|
||||
required
|
||||
type="email"
|
||||
pattern="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
|
||||
[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" *ngIf="emailCtrl.invalid && emailCtrl.touched">
|
||||
<span *ngIf="emailCtrl.errors?.required">Email is required.</span>
|
||||
<span *ngIf="emailCtrl.errors?.pattern">Enter a valid email address.</span>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Specialization -->
|
||||
<div class="field col-md-5">
|
||||
<label for="specialization">Specialization</label>
|
||||
<input pInputText id="specialization" name="specialization" [(ngModel)]="doctor.specialization" />
|
||||
<input
|
||||
pInputText
|
||||
id="specialization"
|
||||
name="specialization"
|
||||
[(ngModel)]="doctor.specialization"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<!-- Experience -->
|
||||
<div class="field col-md-5">
|
||||
<label for="experience">Experience (Years)</label>
|
||||
<input type="number" pInputText id="experience" name="experience" [(ngModel)]="doctor.experience" min="0" />
|
||||
<input
|
||||
type="number"
|
||||
pInputText
|
||||
id="experience"
|
||||
name="experience"
|
||||
[(ngModel)]="doctor.experience"
|
||||
min="0"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Consultation Fee -->
|
||||
<div class="field col-md-5">
|
||||
<label for="consultationFee">Consultation Fee</label>
|
||||
<input type="number" pInputText id="consultationFee" name="consultationFee" [(ngModel)]="doctor.consultationFee" min="0" />
|
||||
<input
|
||||
type="number"
|
||||
pInputText
|
||||
id="consultationFee"
|
||||
name="consultationFee"
|
||||
[(ngModel)]="doctor.consultationFee"
|
||||
min="0"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<!-- Clinic Location -->
|
||||
<div class="field col-md-5">
|
||||
<label for="clinicLocation">Clinic Location</label>
|
||||
<input pInputText id="clinicLocation" name="clinicLocation" [(ngModel)]="doctor.clinicLocation" />
|
||||
<input
|
||||
pInputText
|
||||
id="clinicLocation"
|
||||
name="clinicLocation"
|
||||
[(ngModel)]="doctor.clinicLocation"
|
||||
/>
|
||||
</div>
|
||||
<div class="field col-md-3">
|
||||
<label for="rating">Rating</label><br>
|
||||
<p-rating [(ngModel)]="doctor.rating" [stars]="5" [cancel]="false" name="rating"></p-rating>
|
||||
<div class="field col-md-5">
|
||||
<label for="dateofbirth">Date Of Birth <span class="text-danger">*</span></label>
|
||||
<span class="p-input-icon-left p-input-icon-right">
|
||||
<i class="pi pi-calendar"></i>
|
||||
<p-calendar
|
||||
id="dateofbirth"
|
||||
name="dateofbirth"
|
||||
[(ngModel)]="dateofbirth"
|
||||
#dateofbirthCtrl="ngModel"
|
||||
required
|
||||
[showIcon]="true"
|
||||
dateFormat="dd/mm/yy"
|
||||
[ngClass]="{
|
||||
'is-valid': dateofbirthCtrl.valid && dateofbirthCtrl.touched,
|
||||
'is-invalid': dateofbirthCtrl.invalid && dateofbirthCtrl.touched
|
||||
}"
|
||||
>
|
||||
</p-calendar>
|
||||
<i
|
||||
*ngIf="dateofbirthCtrl.valid && dateofbirthCtrl.touched"
|
||||
class="pi pi-check text-success"
|
||||
></i>
|
||||
<i
|
||||
*ngIf="dateofbirthCtrl.invalid && dateofbirthCtrl.touched"
|
||||
class="pi pi-times text-danger"
|
||||
></i>
|
||||
</span>
|
||||
<small class="text-danger" *ngIf="dateofbirthCtrl.invalid && dateofbirthCtrl.touched">
|
||||
<span *ngIf="dateofbirthCtrl.errors?.required">DOB is required.</span>
|
||||
</small>
|
||||
</div>
|
||||
<div class="field col-md-4">
|
||||
<label for="degree">Degree</label>
|
||||
<input pInputText id="degree" name="degree" [(ngModel)]="doctor.degree" />
|
||||
<div class="field col-md-1"></div>
|
||||
<div class="field col-md-5">
|
||||
<label for="joiningDate">Joining Date <span class="text-danger">*</span></label>
|
||||
<span class="p-input-icon-left p-input-icon-right">
|
||||
<i class="pi pi-calendar"></i>
|
||||
<p-calendar
|
||||
id="joiningDate"
|
||||
name="joiningDate"
|
||||
[(ngModel)]="JoiningDate"
|
||||
#joiningDateCtrl="ngModel"
|
||||
required
|
||||
[showIcon]="true"
|
||||
dateFormat="dd/mm/yy"
|
||||
[ngClass]="{
|
||||
'is-valid': joiningDateCtrl.valid && joiningDateCtrl.touched,
|
||||
'is-invalid': joiningDateCtrl.invalid && joiningDateCtrl.touched
|
||||
}"
|
||||
>
|
||||
</p-calendar>
|
||||
<i
|
||||
*ngIf="joiningDateCtrl.valid && joiningDateCtrl.touched"
|
||||
class="pi pi-check text-success"
|
||||
></i>
|
||||
<i
|
||||
*ngIf="joiningDateCtrl.invalid && joiningDateCtrl.touched"
|
||||
class="pi pi-times text-danger"
|
||||
></i>
|
||||
</span>
|
||||
<small class="text-danger" *ngIf="joiningDateCtrl.invalid && joiningDateCtrl.touched">
|
||||
<span *ngIf="joiningDateCtrl.errors?.required">Joining Date is required.</span>
|
||||
</small>
|
||||
</div>
|
||||
<!-- Rating -->
|
||||
<div class="field col-md-10">
|
||||
<label for="rating">Rating</label><br />
|
||||
<p-rating
|
||||
[(ngModel)]="doctor.rating"
|
||||
[stars]="5"
|
||||
[cancel]="false"
|
||||
name="rating"
|
||||
></p-rating>
|
||||
</div>
|
||||
<div class="field col-md-1"></div>
|
||||
|
||||
<div class="field col-md-3">
|
||||
<!-- <div class="field col-md-5">
|
||||
<label for="availability">Availability</label>
|
||||
<p-dropdown [options]="workScheduleOptions" [(ngModel)]="doctor.availability" name="availability" placeholder="Select Availability"></p-dropdown>
|
||||
<p-dropdown
|
||||
[options]="workScheduleOptions"
|
||||
[(ngModel)]="doctor.availability"
|
||||
name="availability"
|
||||
placeholder="Select Availability"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
></p-dropdown>
|
||||
</div> -->
|
||||
<div class="card p-4">
|
||||
<h4>Doctor Availability Schedule</h4>
|
||||
|
||||
<!-- Add Availability Button -->
|
||||
<div class="field">
|
||||
<button pButton type="button" (click)="addAvailability()" icon="pi pi-plus" label="Add Schedule"></button>
|
||||
</div>
|
||||
|
||||
<!-- Loop Through Availability Schedules -->
|
||||
<div *ngFor="let avail of availabilitySchedules; let i = index" class="availability-container">
|
||||
|
||||
<!-- Work Schedule Selection -->
|
||||
<div class="field col-md-3">
|
||||
<label for="availability-{{ i }}">Select Day</label>
|
||||
<p-dropdown
|
||||
[options]="workScheduleOptions"
|
||||
[(ngModel)]="avail.schedule"
|
||||
name="availability-{{ i }}"
|
||||
placeholder="Select Availability"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
class="w-full"
|
||||
></p-dropdown>
|
||||
</div>
|
||||
|
||||
<!-- Start Time -->
|
||||
<div class="field col-md-3">
|
||||
<label for="start-time-{{ i }}">Start Time</label>
|
||||
<p-calendar
|
||||
id="start-time-{{ i }}"
|
||||
[(ngModel)]="avail.startTime"
|
||||
name="startTime-{{ i }}"
|
||||
showTime
|
||||
timeOnly
|
||||
hourFormat="24"
|
||||
placeholder="Select Start Time"
|
||||
class="w-full"
|
||||
></p-calendar>
|
||||
</div>
|
||||
|
||||
<!-- End Time -->
|
||||
<div class="field col-md-3">
|
||||
<label for="end-time-{{ i }}">End Time</label>
|
||||
<p-calendar
|
||||
id="end-time-{{ i }}"
|
||||
[(ngModel)]="avail.endTime"
|
||||
name="endTime-{{ i }}"
|
||||
showTime
|
||||
timeOnly
|
||||
hourFormat="24"
|
||||
placeholder="Select End Time"
|
||||
class="w-full"
|
||||
></p-calendar>
|
||||
</div>
|
||||
|
||||
<!-- Remove Button -->
|
||||
<div class="field col-md-2 flex align-items-end">
|
||||
<button pButton type="button" (click)="removeAvailability(i)" icon="pi pi-trash" class="p-button-danger"></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Description -->
|
||||
<div class="field col-11">
|
||||
<label for="description">Description</label>
|
||||
<textarea id="description" name="description" [(ngModel)]="doctor.description" rows="5" cols="30" pInputTextarea></textarea>
|
||||
<textarea
|
||||
id="description"
|
||||
name="description"
|
||||
[(ngModel)]="doctor.description"
|
||||
rows="5"
|
||||
cols="30"
|
||||
pInputTextarea
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Buttons -->
|
||||
<div class="field col-11 flex justify-content-end">
|
||||
<button pButton type="submit" label="Save" class="p-button-success" [disabled]="doctorForm.invalid"></button>
|
||||
<button pButton type="button" label="Cancel" class="p-button-secondary ml-2" (click)="onClose()"></button>
|
||||
<button
|
||||
pButton
|
||||
type="submit"
|
||||
label="Save"
|
||||
class="p-button-success"
|
||||
[disabled]="doctorForm.invalid"
|
||||
></button>
|
||||
<button
|
||||
pButton
|
||||
type="button"
|
||||
label="Cancel"
|
||||
class="p-button-secondary ml-2"
|
||||
(click)="onClose()"
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -20,4 +20,16 @@
|
||||
.modal {
|
||||
z-index: 1040; /* Set lower z-index to ensure modal is behind the calendar */
|
||||
}
|
||||
.availability-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 15px;
|
||||
padding: 10px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -14,8 +14,13 @@ import { InputTextareaModule } from 'primeng/inputtextarea';
|
||||
import { RadioButtonModule } from 'primeng/radiobutton';
|
||||
import { TableModule } from 'primeng/table';
|
||||
import { RatingModule } from 'primeng/rating';
|
||||
import { workScheduleOptions } from '@proxy/global-enum';
|
||||
|
||||
import { TimeSlot, WorkSchedule, workScheduleOptions } from '@proxy/global-enum';
|
||||
// Define Type for Availability
|
||||
interface AvailabilitySchedule {
|
||||
schedule: WorkSchedule | null;
|
||||
startTime: Date | null;
|
||||
endTime: Date | null;
|
||||
}
|
||||
@Component({
|
||||
selector: 'app-doctor-dialog',
|
||||
standalone: true,
|
||||
@ -33,7 +38,7 @@ import { workScheduleOptions } from '@proxy/global-enum';
|
||||
InputTextareaModule,
|
||||
ChipModule,
|
||||
CommonModule,
|
||||
RatingModule
|
||||
RatingModule,
|
||||
],
|
||||
templateUrl: './doctor-dialog.component.html',
|
||||
styleUrl: './doctor-dialog.component.scss',
|
||||
@ -48,14 +53,38 @@ export class DoctorDialogComponent implements OnInit {
|
||||
doctorDialog: boolean;
|
||||
JoiningDate: Date;
|
||||
dateofbirth: Date;
|
||||
availabilitySchedules: AvailabilitySchedule[] = []; // Separate storage for availability
|
||||
|
||||
constructor(private DoctorService: DoctorService, private toaster: ToasterService) {}
|
||||
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.isEditMode) {
|
||||
this.fetchDoctorData();
|
||||
}
|
||||
else{
|
||||
this.doctor = {
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
gender: '',
|
||||
mobile: '',
|
||||
password: '',
|
||||
designation: '',
|
||||
departmentId: '',
|
||||
address: '',
|
||||
email: '',
|
||||
dob: '',
|
||||
education: '',
|
||||
specialization: '',
|
||||
degree: '',
|
||||
joiningDate: '',
|
||||
experience: 0,
|
||||
consultationFee: 0,
|
||||
availability: null,
|
||||
timeSlot:null,
|
||||
rating: 0,
|
||||
clinicLocation: '',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
doctor: CreateDoctorDto = {
|
||||
@ -77,15 +106,28 @@ export class DoctorDialogComponent implements OnInit {
|
||||
experience: 0,
|
||||
consultationFee: 0,
|
||||
availability: null,
|
||||
timeSlot:null,
|
||||
|
||||
rating: 0,
|
||||
clinicLocation: '',
|
||||
};
|
||||
workScheduleOptions = Object.keys(workScheduleOptions)
|
||||
.filter(key => isNaN(Number(key)))
|
||||
.map(key => ({
|
||||
label: key.replace(/([A-Z])/g, ' $1').trim(),
|
||||
value: workScheduleOptions[key as keyof typeof workScheduleOptions]
|
||||
}));
|
||||
workScheduleOptions = Object.keys(WorkSchedule)
|
||||
.filter((key) => isNaN(Number(key))) // Only get string keys (not numeric values)
|
||||
.map((key) => ({
|
||||
label: key.replace(/([A-Z])/g, ' $1').trim(), // Format enum keys as readable labels
|
||||
value: WorkSchedule[key as keyof typeof WorkSchedule], // Get enum value
|
||||
}));
|
||||
|
||||
timeSlotOptions: { label: string, value: TimeSlot }[] = [
|
||||
{ label: '10:00 AM - 7:00 PM', value: TimeSlot.TenToSeven },
|
||||
{ label: '09:00 AM - 5:00 PM', value: TimeSlot.NineToFive },
|
||||
{ label: '08:00 AM - 4:00 PM', value: TimeSlot.EightToFour },
|
||||
{ label: '07:00 AM - 4:00 PM', value: TimeSlot.SevenToFour },
|
||||
{ label: '06:00 AM - 3:00 PM', value: TimeSlot.SixToThree },
|
||||
{ label: '12:00 PM - 9:00 PM', value: TimeSlot.TwelveToNine },
|
||||
{ label: '10:00 AM - 6:00 PM', value: TimeSlot.TenToSix },
|
||||
{ label: '11:00 AM - 8:00 PM', value: TimeSlot.ElevenToEight },
|
||||
];
|
||||
fetchDoctorData() {
|
||||
this.DoctorService.getDoctorById(this.Id).subscribe(result => {
|
||||
this.doctor = result;
|
||||
@ -99,7 +141,7 @@ export class DoctorDialogComponent implements OnInit {
|
||||
return;
|
||||
}
|
||||
this.doctor.dob = this.dateofbirth.toDateString();
|
||||
|
||||
this.doctor.joiningDate = this.JoiningDate.toDateString();
|
||||
if (this.isEditMode) {
|
||||
this.DoctorService.updatDoctor(this.doctor).subscribe(
|
||||
() => {
|
||||
@ -126,4 +168,18 @@ export class DoctorDialogComponent implements OnInit {
|
||||
this.Id = '';
|
||||
this.close.emit();
|
||||
}
|
||||
addAvailability() {
|
||||
this.availabilitySchedules.push({ schedule: null, startTime: null, endTime: null });
|
||||
this.syncDoctorAvailability(); // Sync with doctor object
|
||||
}
|
||||
|
||||
removeAvailability(index: number) {
|
||||
this.availabilitySchedules.splice(index, 1);
|
||||
this.syncDoctorAvailability(); // Sync after removal
|
||||
}
|
||||
|
||||
syncDoctorAvailability() {
|
||||
// this.doctor.availability = [...this.availabilitySchedules]; // Keep doctor object updated
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,8 +45,7 @@
|
||||
</ng-template>
|
||||
<ng-template pTemplate="header">
|
||||
<tr>
|
||||
<th pSortableColumn="firstName">First Name <p-sortIcon field="firstName" /></th>
|
||||
<th pSortableColumn="lastName">Last Name <p-sortIcon field="lastName" /></th>
|
||||
<th pSortableColumn="firstName">Name <p-sortIcon field="firstName" /></th>
|
||||
<th pSortableColumn="mobile">Mobile <p-sortIcon field="mobile" /></th>
|
||||
<th pSortableColumn="email">Email <p-sortIcon field="email" /></th>
|
||||
<th pSortableColumn="specialization">Specialization <p-sortIcon field="specialization" /></th>
|
||||
@ -57,8 +56,7 @@
|
||||
</ng-template>
|
||||
<ng-template pTemplate="body" let-doctor>
|
||||
<tr>
|
||||
<td>{{ doctor.firstName }}</td>
|
||||
<td>{{ doctor.lastName }}</td>
|
||||
<td>Dr. {{ doctor.firstName }} {{ doctor.lastName }}</td>
|
||||
<td>{{ doctor.mobile }}</td>
|
||||
<td>{{ doctor.email }}</td>
|
||||
<td>{{ doctor.specialization }}</td>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import type { FullAuditedEntity } from '../../volo/abp/domain/entities/auditing/models';
|
||||
import type { WorkSchedule } from '../../global-enum/work-schedule.enum';
|
||||
import type { TimeSlot } from '../../global-enum/time-slot.enum';
|
||||
|
||||
export interface DoctorDto extends FullAuditedEntity<string> {
|
||||
id?: string;
|
||||
@ -19,6 +20,7 @@ export interface DoctorDto extends FullAuditedEntity<string> {
|
||||
experience?: number;
|
||||
consultationFee?: number;
|
||||
availability?: WorkSchedule;
|
||||
timeSlot: TimeSlot;
|
||||
rating?: number;
|
||||
clinicLocation?: string;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import type { WorkSchedule } from '../global-enum/work-schedule.enum';
|
||||
import type { TimeSlot } from '../global-enum/time-slot.enum';
|
||||
import type { FullAuditedEntity } from '../volo/abp/domain/entities/auditing/models';
|
||||
|
||||
export interface CreateDepartmentDto {
|
||||
@ -30,6 +31,7 @@ export interface CreateDoctorDto {
|
||||
experience?: number;
|
||||
consultationFee?: number;
|
||||
availability?: WorkSchedule;
|
||||
timeSlot: TimeSlot;
|
||||
rating?: number;
|
||||
clinicLocation?: string;
|
||||
}
|
||||
|
@ -5724,6 +5724,18 @@
|
||||
"maximum": null,
|
||||
"regex": null
|
||||
},
|
||||
{
|
||||
"name": "TimeSlot",
|
||||
"jsonName": null,
|
||||
"type": "HospitalManagementSystem.GlobalEnum.TimeSlot",
|
||||
"typeSimple": "HospitalManagementSystem.GlobalEnum.TimeSlot",
|
||||
"isRequired": false,
|
||||
"minLength": null,
|
||||
"maxLength": null,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"regex": null
|
||||
},
|
||||
{
|
||||
"name": "Rating",
|
||||
"jsonName": null,
|
||||
@ -6246,6 +6258,18 @@
|
||||
"maximum": null,
|
||||
"regex": null
|
||||
},
|
||||
{
|
||||
"name": "TimeSlot",
|
||||
"jsonName": null,
|
||||
"type": "HospitalManagementSystem.GlobalEnum.TimeSlot",
|
||||
"typeSimple": "HospitalManagementSystem.GlobalEnum.TimeSlot",
|
||||
"isRequired": false,
|
||||
"minLength": null,
|
||||
"maxLength": null,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"regex": null
|
||||
},
|
||||
{
|
||||
"name": "Rating",
|
||||
"jsonName": null,
|
||||
@ -6415,6 +6439,32 @@
|
||||
"genericArguments": null,
|
||||
"properties": null
|
||||
},
|
||||
"HospitalManagementSystem.GlobalEnum.TimeSlot": {
|
||||
"baseType": "System.Enum",
|
||||
"isEnum": true,
|
||||
"enumNames": [
|
||||
"TenToSeven",
|
||||
"NineToFive",
|
||||
"EightToFour",
|
||||
"SevenToFour",
|
||||
"SixToThree",
|
||||
"TwelveToNine",
|
||||
"TenToSix",
|
||||
"ElevenToEight"
|
||||
],
|
||||
"enumValues": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8
|
||||
],
|
||||
"genericArguments": null,
|
||||
"properties": null
|
||||
},
|
||||
"HospitalManagementSystem.GlobalEnum.visitType": {
|
||||
"baseType": "System.Enum",
|
||||
"isEnum": true,
|
||||
@ -6433,6 +6483,13 @@
|
||||
"baseType": "System.Enum",
|
||||
"isEnum": true,
|
||||
"enumNames": [
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday",
|
||||
"Sunday",
|
||||
"MondayToFriday",
|
||||
"TuesdayToSaturday",
|
||||
"WednesdayToSunday",
|
||||
@ -6446,14 +6503,7 @@
|
||||
"ThursdayToSunday",
|
||||
"FridayToMonday",
|
||||
"SaturdayToTuesday",
|
||||
"SundayToWednesday",
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday",
|
||||
"Sunday"
|
||||
"SundayToWednesday"
|
||||
],
|
||||
"enumValues": [
|
||||
1,
|
||||
|
@ -2,5 +2,6 @@ export * from './appointment-status.enum';
|
||||
export * from './gender.enum';
|
||||
export * from './payment-status.enum';
|
||||
export * from './status.enum';
|
||||
export * from './time-slot.enum';
|
||||
export * from './visit-type.enum';
|
||||
export * from './work-schedule.enum';
|
||||
|
14
angular/src/app/proxy/global-enum/time-slot.enum.ts
Normal file
14
angular/src/app/proxy/global-enum/time-slot.enum.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { mapEnumToOptions } from '@abp/ng.core';
|
||||
|
||||
export enum TimeSlot {
|
||||
TenToSeven = 1,
|
||||
NineToFive = 2,
|
||||
EightToFour = 3,
|
||||
SevenToFour = 4,
|
||||
SixToThree = 5,
|
||||
TwelveToNine = 6,
|
||||
TenToSix = 7,
|
||||
ElevenToEight = 8,
|
||||
}
|
||||
|
||||
export const timeSlotOptions = mapEnumToOptions(TimeSlot);
|
@ -1,27 +1,27 @@
|
||||
import { mapEnumToOptions } from '@abp/ng.core';
|
||||
|
||||
export enum WorkSchedule {
|
||||
MondayToFriday = 1,
|
||||
TuesdayToSaturday = 2,
|
||||
WednesdayToSunday = 3,
|
||||
ThursdayToMonday = 4,
|
||||
FridayToTuesday = 5,
|
||||
SaturdayToWednesday = 6,
|
||||
SundayToThursday = 7,
|
||||
MondayToThursday = 8,
|
||||
TuesdayToFriday = 9,
|
||||
WednesdayToSaturday = 10,
|
||||
ThursdayToSunday = 11,
|
||||
FridayToMonday = 12,
|
||||
SaturdayToTuesday = 13,
|
||||
SundayToWednesday = 14,
|
||||
Monday = 15,
|
||||
Tuesday = 16,
|
||||
Wednesday = 17,
|
||||
Thursday = 18,
|
||||
Friday = 19,
|
||||
Saturday = 20,
|
||||
Sunday = 21,
|
||||
Monday = 1,
|
||||
Tuesday = 2,
|
||||
Wednesday = 3,
|
||||
Thursday = 4,
|
||||
Friday = 5,
|
||||
Saturday = 6,
|
||||
Sunday = 7,
|
||||
MondayToFriday = 8,
|
||||
TuesdayToSaturday = 9,
|
||||
WednesdayToSunday = 10,
|
||||
ThursdayToMonday = 11,
|
||||
FridayToTuesday = 12,
|
||||
SaturdayToWednesday = 13,
|
||||
SundayToThursday = 14,
|
||||
MondayToThursday = 15,
|
||||
TuesdayToFriday = 16,
|
||||
WednesdayToSaturday = 17,
|
||||
ThursdayToSunday = 18,
|
||||
FridayToMonday = 19,
|
||||
SaturdayToTuesday = 20,
|
||||
SundayToWednesday = 21,
|
||||
}
|
||||
|
||||
export const workScheduleOptions = mapEnumToOptions(WorkSchedule);
|
||||
|
22
angular/src/app/room-management/rooms.component.html
Normal file
22
angular/src/app/room-management/rooms.component.html
Normal file
@ -0,0 +1,22 @@
|
||||
<div class="room-management-container">
|
||||
<h2 class="heading">Room Management</h2>
|
||||
|
||||
<!-- Date Selection using PrimeNG -->
|
||||
<div class="date-header">
|
||||
<label for="date">Select Date:</label>
|
||||
<p-calendar id="date" [(ngModel)]="selectedDate" dateFormat="dd-mm-yy" (onSelect)="onDateChange()" showIcon></p-calendar>
|
||||
</div>
|
||||
|
||||
<!-- Room Grid -->
|
||||
<div class="room-container p-grid">
|
||||
<div *ngFor="let room of roomData" class="p-col-12 p-md-3">
|
||||
<p-button
|
||||
[label]="room.roomName"
|
||||
[severity]="getRoomStatus(room.roomName) === 'occupied' ? 'danger' : 'success'"
|
||||
class="room-button"
|
||||
(click)="selectRoom(room.roomName)">
|
||||
</p-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
45
angular/src/app/room-management/rooms.component.scss
Normal file
45
angular/src/app/room-management/rooms.component.scss
Normal file
@ -0,0 +1,45 @@
|
||||
/* General Styling */
|
||||
.room-management-container {
|
||||
padding: 20px;
|
||||
font-family: 'Arial', sans-serif;
|
||||
background-color: #f4f7fa;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.heading {
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Date Picker */
|
||||
.date-header {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.date-header label {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Room Grid */
|
||||
.room-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
/* Room Buttons */
|
||||
.room-button {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
23
angular/src/app/room-management/rooms.component.spec.ts
Normal file
23
angular/src/app/room-management/rooms.component.spec.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { RoomsComponent } from './rooms.component';
|
||||
|
||||
describe('RoomsComponent', () => {
|
||||
let component: RoomsComponent;
|
||||
let fixture: ComponentFixture<RoomsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [RoomsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(RoomsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
60
angular/src/app/room-management/rooms.component.ts
Normal file
60
angular/src/app/room-management/rooms.component.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-rooms',
|
||||
|
||||
templateUrl: './rooms.component.html',
|
||||
styleUrl: './rooms.component.scss'
|
||||
})
|
||||
export class RoomsComponent {
|
||||
|
||||
selectedDate: Date = new Date(); // Default to today
|
||||
|
||||
roomData = [
|
||||
{ roomName: 'Room 101' },
|
||||
{ roomName: 'Room 102' },
|
||||
{ roomName: 'Room 103' },
|
||||
{ roomName: 'Room 104' },
|
||||
{ roomName: 'Room 201' },
|
||||
{ roomName: 'Room 202' },
|
||||
{ roomName: 'Room 203' },
|
||||
{ roomName: 'Room 301' },
|
||||
{ roomName: 'Room 302' },
|
||||
{ roomName: 'Room 303' },
|
||||
{ roomName: 'Room 401' },
|
||||
{ roomName: 'Room 402' },
|
||||
// Add more rooms as necessary
|
||||
];
|
||||
|
||||
roomStatus = {
|
||||
'Room 101': 'occupied',
|
||||
'Room 102': 'available',
|
||||
'Room 103': 'available',
|
||||
'Room 104': 'occupied',
|
||||
'Room 201': 'available',
|
||||
'Room 202': 'occupied',
|
||||
'Room 203': 'available',
|
||||
'Room 301': 'available',
|
||||
'Room 302': 'occupied',
|
||||
'Room 303': 'available',
|
||||
'Room 401': 'occupied',
|
||||
'Room 402': 'available',
|
||||
// Add more rooms and statuses as necessary
|
||||
};
|
||||
onDateChange() {
|
||||
console.log('Selected date:', this.selectedDate);
|
||||
// Logic to handle room status based on selected date, if needed
|
||||
}
|
||||
selectRoom(room: string) {
|
||||
// Logic for selecting a room
|
||||
console.log(`${room} selected.`);
|
||||
}
|
||||
|
||||
getRoomStatus(room: string) {
|
||||
return this.roomStatus[room] || 'available'; // Default to 'available' if not specified
|
||||
}
|
||||
|
||||
getRoomStatusLabel(room: string) {
|
||||
return this.getRoomStatus(room) === 'available' ? 'Available' : 'Occupied';
|
||||
}
|
||||
}
|
@ -91,6 +91,21 @@ function configureRoutes(routesService: RoutesService) {
|
||||
order: 402,
|
||||
requiredPolicy:'HospitalManagementSystem.Doctor'
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
name: 'Rooms',
|
||||
order: 501,
|
||||
iconClass: 'fas fa-user-md',
|
||||
layout: eLayoutType.application,
|
||||
},
|
||||
{
|
||||
path: '/rooms',
|
||||
name: 'All Rooms',
|
||||
parentName: 'Rooms',
|
||||
iconClass: 'fas fa-clock',
|
||||
order: 502,
|
||||
requiredPolicy:'HospitalManagementSystem.Doctor'
|
||||
},
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ namespace HospitalManagementSystem.Doctors.Dto
|
||||
public int? Experience { get; set; }
|
||||
public decimal? ConsultationFee { get; set; }
|
||||
public WorkSchedule? Availability { get; set; }
|
||||
public TimeSlot TimeSlot { get; set; }
|
||||
public decimal? Rating { get; set; }
|
||||
public string? ClinicLocation { get; set; }
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ namespace HospitalManagementSystem.Doctors
|
||||
worksheet.Cell(i + 2, 2).Value = DoctorRecord[i].Email;
|
||||
worksheet.Cell(i + 2, 3).Value = DoctorRecord[i].Specialization;
|
||||
worksheet.Cell(i + 2, 4).Value = DoctorRecord[i].JoiningDate?.ToShortDateString();
|
||||
worksheet.Cell(i + 2, 5).Value = DoctorRecord[i].Department.DepartmentName;
|
||||
worksheet.Cell(i + 2, 5).Value = DoctorRecord[i].Department==null?"": DoctorRecord[i].Department.DepartmentName;
|
||||
worksheet.Cell(i + 2, 6).Value = DoctorRecord[i].Mobile;
|
||||
worksheet.Cell(i + 2, 6).Value = DoctorRecord[i].Degree;
|
||||
worksheet.Cell(i + 2, 6).Value = DoctorRecord[i].Experience;
|
||||
@ -138,9 +138,7 @@ namespace HospitalManagementSystem.Doctors
|
||||
worksheet.Cell(i + 2, 6).Value = DoctorRecord[i].Availability.ToString();
|
||||
worksheet.Cell(i + 2, 6).Value = DoctorRecord[i].Rating;
|
||||
worksheet.Cell(i + 2, 6).Value = DoctorRecord[i].ClinicLocation;
|
||||
|
||||
}
|
||||
|
||||
worksheet.Columns().AdjustToContents();
|
||||
workbook.SaveAs(filePath);
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ namespace HospitalManagementSystem.Dtos
|
||||
public int? Experience { get; set; }
|
||||
public decimal? ConsultationFee { get; set; }
|
||||
public WorkSchedule? Availability { get; set; }
|
||||
public TimeSlot TimeSlot { get; set; }
|
||||
|
||||
public decimal? Rating { get; set; }
|
||||
public string? ClinicLocation { get; set; }
|
||||
}
|
||||
|
@ -39,28 +39,42 @@ namespace HospitalManagementSystem.GlobalEnum
|
||||
|
||||
public enum WorkSchedule
|
||||
{
|
||||
MondayToFriday = 1,
|
||||
TuesdayToSaturday = 2,
|
||||
WednesdayToSunday = 3,
|
||||
ThursdayToMonday = 4,
|
||||
FridayToTuesday = 5,
|
||||
SaturdayToWednesday = 6,
|
||||
SundayToThursday = 7,
|
||||
MondayToThursday = 8,
|
||||
TuesdayToFriday = 9,
|
||||
WednesdayToSaturday = 10,
|
||||
ThursdayToSunday = 11,
|
||||
FridayToMonday = 12,
|
||||
SaturdayToTuesday = 13,
|
||||
SundayToWednesday = 14,
|
||||
Monday = 15,
|
||||
Tuesday = 16,
|
||||
Wednesday = 17,
|
||||
Thursday = 18,
|
||||
Friday = 19,
|
||||
Saturday = 20,
|
||||
Sunday = 21
|
||||
Monday = 1,
|
||||
Tuesday = 2,
|
||||
Wednesday = 3,
|
||||
Thursday = 4,
|
||||
Friday = 5,
|
||||
Saturday = 6,
|
||||
Sunday = 7,
|
||||
MondayToFriday = 8,
|
||||
TuesdayToSaturday = 9,
|
||||
WednesdayToSunday = 10,
|
||||
ThursdayToMonday = 11,
|
||||
FridayToTuesday = 12,
|
||||
SaturdayToWednesday = 13,
|
||||
SundayToThursday = 14,
|
||||
MondayToThursday = 15,
|
||||
TuesdayToFriday = 16,
|
||||
WednesdayToSaturday = 17,
|
||||
ThursdayToSunday = 18,
|
||||
FridayToMonday = 19,
|
||||
SaturdayToTuesday = 20,
|
||||
SundayToWednesday = 21
|
||||
|
||||
}
|
||||
public enum TimeSlot
|
||||
{
|
||||
TenToSeven = 1, // 10:00 AM to 7:00 PM
|
||||
NineToFive = 2, // 09:00 AM to 5:00 PM
|
||||
EightToFour = 3, // 08:00 AM to 4:00 PM
|
||||
SevenToFour = 4, // 07:00 AM to 4:00 PM
|
||||
SixToThree = 5, // 06:00 AM to 3:00 PM
|
||||
TwelveToNine = 6, // 12:00 PM to 9:00 PM
|
||||
TenToSix = 7, // 10:00 AM to 6:00 PM
|
||||
ElevenToEight = 8, // 11:00 AM to 8:00 PM
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user