Service tabs updated

This commit is contained in:
2025-11-20 16:21:48 +05:30
parent 1aa92b7501
commit 4286934d9d
9 changed files with 144 additions and 34 deletions

View File

@ -426,6 +426,42 @@
font-size: 14px;
flex: 1;
}
/* Add to existing CSS */
.badge-group {
display: flex;
align-items: center;
gap: 8px;
}
.category-badge {
display: inline-flex;
align-items: center;
padding: 4px 10px;
background: #e0e7ff;
color: #4338ca;
border-radius: 6px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
}
/* Select dropdown styling */
select.form-input {
cursor: pointer;
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%236b7280' d='M6 9L1 4h10z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
padding-right: 40px;
}
select.form-input:focus {
outline: none;
border-color: #3b82f6;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
/* Form Styles */
.form-section {

View File

@ -31,12 +31,15 @@
<div class="service-tile-info">
<div class="service-tile-header-row">
<h3>{{ serviceTile?.title }}</h3>
<span class="status-badge" [class.status-active]="serviceTile?.isActive"
[class.status-inactive]="!serviceTile?.isActive">
<i class="fa" [class.fa-check-circle]="serviceTile?.isActive"
[class.fa-times-circle]="!serviceTile?.isActive"></i>
{{ serviceTile?.isActive ? 'Active' : 'Inactive' }}
</span>
<div class="badge-group">
<span class="category-badge">{{ getCategoryLabel(serviceTile?.category) }}</span>
<span class="status-badge" [class.status-active]="serviceTile?.isActive"
[class.status-inactive]="!serviceTile?.isActive">
<i class="fa" [class.fa-check-circle]="serviceTile?.isActive"
[class.fa-times-circle]="!serviceTile?.isActive"></i>
{{ serviceTile?.isActive ? 'Active' : 'Inactive' }}
</span>
</div>
</div>
<p class="description" *ngIf="serviceTile?.description">
{{ serviceTile.description }}</p>
@ -92,14 +95,20 @@
</div>
<div class="modal-body">
<div class="service-tile-detail-card">
<div class="detail-item"><span class="detail-label">Title:</span>
<div class="detail-item">
<span class="detail-label">Title:</span>
<span class="detail-value">{{ selectedServiceTile.title }}</span>
</div>
<div class="detail-item"><span class="detail-label">Description:</span>
<div class="detail-item">
<span class="detail-label">Category:</span>
<span class="detail-value">{{ getCategoryLabel(selectedServiceTile.category) }}</span>
</div>
<div class="detail-item">
<span class="detail-label">Description:</span>
<span class="detail-value">{{ selectedServiceTile.description }}</span>
</div>
<div class="detail-item"><span class="detail-label">Display
Order:</span>
<div class="detail-item">
<span class="detail-label">Display Order:</span>
<span class="detail-value">{{ selectedServiceTile.displayOrder }}</span>
</div>
</div>
@ -118,7 +127,8 @@
<div class="modal-header">
<h3>Add New Service Tile</h3>
<button type="button" class="modal-close" data-bs-dismiss="modal">
<i class="fa fa-times"></i></button>
<i class="fa fa-times"></i>
</button>
</div>
<div class="modal-body">
<div class="form-section">
@ -126,11 +136,21 @@
<label>Title *</label>
<input class="form-input" name="title" ngModel required>
</div>
<div class="form-group">
<label>Category *</label>
<select class="form-input" name="category" ngModel required>
<option value="" disabled selected>Select Category</option>
<option *ngFor="let cat of categories" [value]="cat.value">{{ cat.label }}</option>
</select>
</div>
<div class="form-group">
<label>Description * (Separate points with commas)</label>
<textarea class="form-textarea" name="description" ngModel required
placeholder="e.g., Point one, Point two, Point three"></textarea>
</div>
<div class="form-group">
<label>Display Order</label>
<input type="number" class="form-input" name="displayOrder" ngModel value="0">
@ -155,7 +175,8 @@
<div class="modal-header">
<h3>Edit Service Tile</h3>
<button type="button" class="modal-close" data-bs-dismiss="modal">
<i class="fa fa-times"></i></button>
<i class="fa fa-times"></i>
</button>
</div>
<div class="modal-body">
<div class="form-section">
@ -163,11 +184,21 @@
<label>Title *</label>
<input class="form-input" name="title" [(ngModel)]="selectedServiceTile.title" required>
</div>
<div class="form-group">
<label>Category *</label>
<select class="form-input" name="category" [(ngModel)]="selectedServiceTile.category" required>
<option value="" disabled>Select Category</option>
<option *ngFor="let cat of categories" [value]="cat.value">{{ cat.label }}</option>
</select>
</div>
<div class="form-group">
<label>Description * (Separate points with commas)</label>
<textarea class="form-textarea" name="description" [(ngModel)]="selectedServiceTile.description"
required placeholder="e.g., Point one, Point two, Point three"></textarea>
</div>
<div class="form-group">
<label>Display Order</label>
<input type="number" class="form-input" name="displayOrder"

View File

@ -29,7 +29,12 @@ export class ServiceTileComponent implements OnInit, OnDestroy, AfterViewInit {
public refreshing: boolean = false;
private subs = new SubSink();
// ✅ Modal references (No hidden button clicks anymore)
// Category options
public categories = [
{ value: 'ACUTE_CARE_SURGERY', label: 'Acute Care Surgery' },
{ value: 'TRAUMA_CARE', label: 'Trauma Care' }
];
@ViewChild('addServiceTileModal') addServiceTileModal!: ElementRef;
@ViewChild('editServiceTileModal') editServiceTileModal!: ElementRef;
@ViewChild('viewServiceTileModal') viewServiceTileModal!: ElementRef;
@ -50,16 +55,14 @@ export class ServiceTileComponent implements OnInit, OnDestroy, AfterViewInit {
}
ngAfterViewInit(): void {
// ✅ Initialize Bootstrap modal instances
this.addModal = new Modal(this.addServiceTileModal.nativeElement);
this.editModal = new Modal(this.editServiceTileModal.nativeElement);
this.viewModal = new Modal(this.viewServiceTileModal.nativeElement);
}
openAddModal(): void {
this.addModal.show();
}
openAddModal(): void {
this.addModal.show();
}
ngOnDestroy(): void {
this.subs.unsubscribe();
@ -88,7 +91,7 @@ export class ServiceTileComponent implements OnInit, OnDestroy, AfterViewInit {
public onSelectServiceTile(serviceTile: ServiceTile): void {
this.selectedServiceTile = { ...serviceTile };
this.viewModal.show(); // ✅ Show view modal
this.viewModal.show();
}
public onAddNewServiceTile(form: NgForm): void {
@ -98,8 +101,9 @@ export class ServiceTileComponent implements OnInit, OnDestroy, AfterViewInit {
this.subs.sink = this.serviceTileService.addServiceTile(formData).subscribe(
serviceTile => {
this.getServiceTiles(false);
this.addModal.hide(); // ✅ Close modal cleanly
this.addModal.hide();
form.reset();
this.notificationService.notify(NotificationType.SUCCESS, 'Service tile created successfully');
},
(errorResponse: HttpErrorResponse) => {
this.sendErrorNotification(errorResponse.error.message);
@ -109,7 +113,7 @@ export class ServiceTileComponent implements OnInit, OnDestroy, AfterViewInit {
public onEditServiceTile(serviceTile: ServiceTile): void {
this.selectedServiceTile = { ...serviceTile };
this.editModal.show(); // ✅ Show edit modal
this.editModal.show();
}
public onUpdateServiceTile(form: NgForm): void {
@ -123,7 +127,8 @@ export class ServiceTileComponent implements OnInit, OnDestroy, AfterViewInit {
this.subs.sink = this.serviceTileService.updateServiceTile(this.selectedServiceTile.id!, formData).subscribe(
() => {
this.getServiceTiles(false);
this.editModal.hide(); // ✅ Close modal cleanly
this.editModal.hide();
this.notificationService.notify(NotificationType.SUCCESS, 'Service tile updated successfully');
},
(errorResponse: HttpErrorResponse) => {
this.sendErrorNotification(errorResponse.error.message);
@ -160,13 +165,23 @@ export class ServiceTileComponent implements OnInit, OnDestroy, AfterViewInit {
searchTerm = searchTerm.toLowerCase();
this.serviceTiles = this.serviceTileService.getServiceTilesFromLocalStorage()
.filter(t => t.title?.toLowerCase().includes(searchTerm) || t.description?.toLowerCase().includes(searchTerm));
.filter(t =>
t.title?.toLowerCase().includes(searchTerm) ||
t.description?.toLowerCase().includes(searchTerm) ||
this.getCategoryLabel(t.category).toLowerCase().includes(searchTerm)
);
}
public getCategoryLabel(category: string): string {
const cat = this.categories.find(c => c.value === category);
return cat ? cat.label : category;
}
private createServiceTileFormData(serviceTile: any): FormData {
const formData = new FormData();
formData.append('title', serviceTile.title || '');
formData.append('description', serviceTile.description || '');
formData.append('category', serviceTile.category || '');
formData.append('displayOrder', (serviceTile.displayOrder || 0).toString());
return formData;
}
@ -182,4 +197,4 @@ export class ServiceTileComponent implements OnInit, OnDestroy, AfterViewInit {
public get isManager(): boolean {
return this.isAdmin || (this.loggedInUser && this.loggedInUser.role === Role.MANAGER);
}
}
}

View File

@ -2,6 +2,7 @@ export interface ServiceTile {
id?: number;
title: string;
description: string;
category: 'TRAUMA_CARE' | 'ACUTE_CARE_SURGERY';
isActive: boolean;
displayOrder?: number;
createdDate?: Date;