feat: add RBI circulars, CKYC, KYC, Superset analytics, passbook modules and UI updates

Add new feature modules (RBI feeds, CKYC, KYC tab, Form60, Superset analytics, passbook),
update client family members, dashboard, login page, sidenav, images, translations,
environment config, and fix RBI feeds API auth by using relative URLs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Aditya
2026-03-10 15:13:35 +05:30
co-authored by Claude Opus 4.6
parent 07f701f654
commit 73aa69ee02
84 changed files with 6256 additions and 700 deletions
@@ -0,0 +1,144 @@
<!--
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="rbi-container">
<!-- Header -->
<div class="rbi-header">
<div class="rbi-header-left">
<div class="rbi-title">
<fa-icon icon="newspaper" class="title-icon"></fa-icon>
<h2>RBI Circulars & Notifications</h2>
</div>
<span class="rbi-subtitle">Stay updated with the latest Reserve Bank of India communications</span>
</div>
<div class="rbi-header-actions">
<button
mat-raised-button
color="primary"
(click)="refreshFeeds()"
[disabled]="isRefreshing"
matTooltip="Fetch latest feeds from RBI"
>
<fa-icon icon="sync" class="mr-05"></fa-icon>
{{ isRefreshing ? 'Fetching...' : 'Refresh Feeds' }}
</button>
</div>
</div>
<!-- Search Bar -->
<div class="search-bar">
<mat-form-field class="search-field" appearance="outline">
<mat-label>Search circulars...</mat-label>
<input
matInput
[value]="searchText"
(input)="onSearchChange($any($event.target).value)"
placeholder="Search by title or description"
/>
<fa-icon matSuffix icon="search" class="search-icon"></fa-icon>
</mat-form-field>
</div>
<!-- Tabs always visible -->
<mat-tab-group animationDuration="200ms" class="rbi-tabs">
<mat-tab *ngFor="let tab of tabs">
<!-- Tab Label -->
<ng-template mat-tab-label>
<div class="tab-label">
<fa-icon [icon]="tab.icon" class="tab-icon" [style.color]="tab.color"></fa-icon>
<span>{{ tab.label }}</span>
<span class="tab-badge" [style.background]="tab.color">{{ tab.dataSource.filteredData.length }}</span>
</div>
</ng-template>
<!-- Tab Content -->
<div class="tab-content">
<!-- Loading State -->
<div *ngIf="isLoading" class="loading-state">
<mat-spinner diameter="40"></mat-spinner>
<p>Loading RBI circulars...</p>
</div>
<!-- Error State -->
<div *ngIf="errorMessage && !isLoading" class="error-state">
<fa-icon icon="exclamation-triangle" class="error-icon"></fa-icon>
<p>{{ errorMessage }}</p>
<button mat-raised-button color="primary" (click)="loadFeeds()">
<fa-icon icon="sync" class="mr-05"></fa-icon> Retry
</button>
</div>
<!-- Empty state for this tab -->
<div *ngIf="!isLoading && !errorMessage && tab.dataSource.filteredData.length === 0" class="empty-state">
<fa-icon icon="archive" class="empty-icon"></fa-icon>
<h3>No {{ tab.label.toLowerCase() }} found</h3>
<p *ngIf="searchText">No results matching "{{ searchText }}"</p>
<p *ngIf="!searchText">Click "Refresh Feeds" to fetch the latest RBI communications</p>
</div>
<!-- Data Table -->
<div *ngIf="!isLoading && !errorMessage && tab.dataSource.filteredData.length > 0" class="table-wrapper">
<table mat-table [dataSource]="tab.dataSource" class="feed-table">
<!-- S.No Column -->
<ng-container matColumnDef="sno">
<th mat-header-cell *matHeaderCellDef class="col-sno">S.No</th>
<td mat-cell *matCellDef="let row" class="col-sno">
{{ getRowIndex(tab, row) }}
</td>
</ng-container>
<!-- Title Column -->
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef>Title</th>
<td mat-cell *matCellDef="let row" class="col-title">
<div class="title-cell">
<span class="new-badge" *ngIf="isNew(row.pubDate)">NEW</span>
<span class="title-text">{{ row.title }}</span>
</div>
<div *ngIf="row.description" class="description-text">{{ stripHtml(row.description) }}</div>
</td>
</ng-container>
<!-- Date Column -->
<ng-container matColumnDef="pubDate">
<th mat-header-cell *matHeaderCellDef class="col-date">Published Date</th>
<td mat-cell *matCellDef="let row" class="col-date">
<div class="date-cell">
<fa-icon icon="calendar-alt" class="date-icon"></fa-icon>
{{ formatDate(row.pubDate) }}
</div>
</td>
</ng-container>
<!-- Actions Column -->
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef class="col-actions">Link</th>
<td mat-cell *matCellDef="let row" class="col-actions">
<button
mat-raised-button
color="primary"
class="view-btn"
(click)="openLink(row.link)"
matTooltip="Open on RBI website"
>
<fa-icon icon="external-link-alt" class="mr-05"></fa-icon>
View
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="feed-row"></tr>
</table>
<div class="results-info">Showing {{ tab.dataSource.filteredData.length }} items</div>
</div>
</div>
</mat-tab>
</mat-tab-group>
</div>