Files
cbsnexora/src/app/cfcfrms/complaint-list/complaint-list.component.html
T

163 lines
7.5 KiB
HTML

<!--
Copyright since 2025 Mifos Initiative
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->
<div class="complaint-list-page">
<div class="page-header">
<div>
<h2>{{ 'labels.menus.Complaint Management' | translate }}</h2>
<p class="subtitle">{{ 'labels.text.I4C/MHA CFCFRMS Complaint Tickets' | translate }}</p>
</div>
<button mat-raised-button color="accent" (click)="exportCsv()" [disabled]="complaints.length === 0">
<fa-icon icon="file-csv" class="mr-05"></fa-icon> {{ 'labels.text.Export CSV' | translate }}
</button>
</div>
<!-- Filter Chips -->
<div class="filter-chips">
<button mat-stroked-button [class.active-chip]="activeChip === 'ALL'" (click)="onChipClick('ALL')">
{{ 'labels.text.All' | translate }}
</button>
<button mat-stroked-button [class.active-chip]="activeChip === 'PENDING'" (click)="onChipClick('PENDING')">
<span class="chip-dot pending"></span> {{ 'labels.text.Pending' | translate }}
</button>
<button mat-stroked-button [class.active-chip]="activeChip === 'ACTIVE'" (click)="onChipClick('ACTIVE')">
<span class="chip-dot active"></span> {{ 'labels.text.Active' | translate }}
</button>
<button mat-stroked-button [class.active-chip]="activeChip === 'RESOLVED'" (click)="onChipClick('RESOLVED')">
<span class="chip-dot resolved"></span> {{ 'labels.text.Resolved' | translate }}
</button>
</div>
<!-- Filter Bar -->
<mat-card class="filter-bar">
<mat-card-content>
<div class="filter-row">
<mat-form-field appearance="outline" class="filter-field">
<mat-label>{{ 'labels.text.Search by Ticket ID / Mobile' | translate }}</mat-label>
<input
matInput
[(ngModel)]="searchQuery"
(keyup.enter)="onSearch()"
placeholder="{{ 'labels.text.Enter ticket ID or mobile...' | translate }}"
/>
<button mat-icon-button matSuffix (click)="onSearch()">
<fa-icon icon="search"></fa-icon>
</button>
</mat-form-field>
<mat-form-field appearance="outline" class="filter-field">
<mat-label>{{ 'labels.text.Status' | translate }}</mat-label>
<mat-select [(ngModel)]="statusFilter" (selectionChange)="onStatusFilterChange()">
<mat-option value="">{{ 'labels.text.All Statuses' | translate }}</mat-option>
@for (s of statuses; track s) {
<mat-option [value]="s">{{ s.replace('_', ' ') }}</mat-option>
}
</mat-select>
</mat-form-field>
<mat-form-field appearance="outline" class="filter-field">
<mat-label>{{ 'labels.text.From Date' | translate }}</mat-label>
<input matInput [matDatepicker]="fromPicker" [(ngModel)]="dateFrom" (dateChange)="onSearch()" />
<mat-datepicker-toggle matSuffix [for]="fromPicker"></mat-datepicker-toggle>
<mat-datepicker #fromPicker></mat-datepicker>
</mat-form-field>
<mat-form-field appearance="outline" class="filter-field">
<mat-label>{{ 'labels.text.To Date' | translate }}</mat-label>
<input matInput [matDatepicker]="toPicker" [(ngModel)]="dateTo" (dateChange)="onSearch()" />
<mat-datepicker-toggle matSuffix [for]="toPicker"></mat-datepicker-toggle>
<mat-datepicker #toPicker></mat-datepicker>
</mat-form-field>
<button mat-icon-button matTooltip="{{ 'labels.text.Clear Filters' | translate }}" (click)="clearFilters()">
<fa-icon icon="times-circle"></fa-icon>
</button>
</div>
</mat-card-content>
</mat-card>
<!-- Table -->
<mat-card class="table-card">
<mat-card-content>
@if (isLoading) {
<div class="loading-container">
<mat-spinner diameter="40"></mat-spinner>
</div>
} @else if (complaints.length === 0) {
<div class="empty-state">
<fa-icon icon="inbox" size="3x"></fa-icon>
<p>{{ 'labels.text.No complaints match your filters' | translate }}</p>
<button mat-stroked-button (click)="clearFilters()">{{ 'labels.text.Clear Filters' | translate }}</button>
</div>
} @else {
<div class="table-responsive">
<table mat-table [dataSource]="complaints" class="full-width">
<ng-container matColumnDef="ticketId">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.text.Ticket ID' | translate }}</th>
<td mat-cell *matCellDef="let row">
<a [routerLink]="['/cfcfrms/complaints', row.ticketId]" class="ticket-link">{{ row.ticketId }}</a>
</td>
</ng-container>
<ng-container matColumnDef="complainantName">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.text.Complainant' | translate }}</th>
<td mat-cell *matCellDef="let row">{{ row.complainantName }}</td>
</ng-container>
<ng-container matColumnDef="complainantMobile">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.text.Mobile' | translate }}</th>
<td mat-cell *matCellDef="let row">{{ row.complainantMobile }}</td>
</ng-container>
<ng-container matColumnDef="fraudAmount">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.text.Fraud Amount' | translate }}</th>
<td mat-cell *matCellDef="let row" class="amount-cell">{{ formatCurrency(row.fraudAmount) }}</td>
</ng-container>
<ng-container matColumnDef="suspectAccountNumber">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.text.Suspect Account' | translate }}</th>
<td mat-cell *matCellDef="let row" class="mono">{{ row.suspectAccountNumber }}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.text.Status' | translate }}</th>
<td mat-cell *matCellDef="let row">
<mifosx-cfcfrms-status-badge [status]="row.status"></mifosx-cfcfrms-status-badge>
</td>
</ng-container>
<ng-container matColumnDef="createdAt">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.text.Created At' | translate }}</th>
<td mat-cell *matCellDef="let row">{{ formatDate(row.createdAt) }}</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.text.Actions' | translate }}</th>
<td mat-cell *matCellDef="let row">
<a
mat-icon-button
color="primary"
[routerLink]="['/cfcfrms/complaints', row.ticketId]"
matTooltip="{{ 'labels.text.View Details' | translate }}"
>
<fa-icon icon="eye"></fa-icon>
</a>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
</div>
<mat-paginator
[length]="totalElements"
[pageSize]="pageSize"
[pageIndex]="pageIndex"
[pageSizeOptions]="[10, 25, 50]"
(page)="onPageChange($event)"
showFirstLastButtons
>
</mat-paginator>
}
</mat-card-content>
</mat-card>
</div>