feat: client extra fields + KYC home-visit & video-KYC dialogs
- Add Education Level, Degree/Qualification, Religion, Social Category dropdowns (individual clients) with dependent filtering on the create/edit/preview/view flows - Add Agriculture Income & Non-Agriculture Income fields under Financial & Classification - Gate Save with a Verify Client alert dialog when sanctions screening is not yet performed - Trim Office Name and CKYC Number columns from clients list; widen table to fill container - Remove DIP/Screening log IDs from preview and personal-data tabs - Rename "Branch Visit" to "Home Visit" across KYC management - Wire Take Action: open dedicated dialogs for Schedule Home Visit (officer + datetime) and Send Video KYC link (channels + officer + 48h expiry + session preview) - Migrate Signatory and Guardian image dialogs to inject() for prefer-inject lint rule Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
d72e969dc3
commit
52e3395345
+495
-164
@@ -42,7 +42,9 @@
|
|||||||
<mat-select-trigger>
|
<mat-select-trigger>
|
||||||
@if (createClientForm.get('legalFormId')?.value) {
|
@if (createClientForm.get('legalFormId')?.value) {
|
||||||
<span class="legal-form-option">
|
<span class="legal-form-option">
|
||||||
<mat-icon class="legal-form-option-icon">{{ createClientForm.get('legalFormId')?.value === 1 ? 'person' : 'business' }}</mat-icon>
|
<mat-icon class="legal-form-option-icon">{{
|
||||||
|
createClientForm.get('legalFormId')?.value === 1 ? 'person' : 'business'
|
||||||
|
}}</mat-icon>
|
||||||
{{ getSelectedLegalFormLabel() }}
|
{{ getSelectedLegalFormLabel() }}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
@@ -67,12 +69,12 @@
|
|||||||
@if (getSelectedNationality().flagType === 'india') {
|
@if (getSelectedNationality().flagType === 'india') {
|
||||||
<span class="nat-flag">
|
<span class="nat-flag">
|
||||||
<svg viewBox="0 0 36 24" class="nat-flag-svg">
|
<svg viewBox="0 0 36 24" class="nat-flag-svg">
|
||||||
<rect width="36" height="8" fill="#FF9933"/>
|
<rect width="36" height="8" fill="#FF9933" />
|
||||||
<rect y="8" width="36" height="8" fill="#FFFFFF"/>
|
<rect y="8" width="36" height="8" fill="#FFFFFF" />
|
||||||
<rect y="16" width="36" height="8" fill="#138808"/>
|
<rect y="16" width="36" height="8" fill="#138808" />
|
||||||
<circle cx="18" cy="12" r="3" fill="#000080"/>
|
<circle cx="18" cy="12" r="3" fill="#000080" />
|
||||||
<circle cx="18" cy="12" r="2.5" fill="#FFFFFF"/>
|
<circle cx="18" cy="12" r="2.5" fill="#FFFFFF" />
|
||||||
<circle cx="18" cy="12" r="0.7" fill="#000080"/>
|
<circle cx="18" cy="12" r="0.7" fill="#000080" />
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
} @else {
|
} @else {
|
||||||
@@ -88,12 +90,12 @@
|
|||||||
@if (nat.flagType === 'india') {
|
@if (nat.flagType === 'india') {
|
||||||
<span class="nat-flag">
|
<span class="nat-flag">
|
||||||
<svg viewBox="0 0 36 24" class="nat-flag-svg">
|
<svg viewBox="0 0 36 24" class="nat-flag-svg">
|
||||||
<rect width="36" height="8" fill="#FF9933"/>
|
<rect width="36" height="8" fill="#FF9933" />
|
||||||
<rect y="8" width="36" height="8" fill="#FFFFFF"/>
|
<rect y="8" width="36" height="8" fill="#FFFFFF" />
|
||||||
<rect y="16" width="36" height="8" fill="#138808"/>
|
<rect y="16" width="36" height="8" fill="#138808" />
|
||||||
<circle cx="18" cy="12" r="3" fill="#000080"/>
|
<circle cx="18" cy="12" r="3" fill="#000080" />
|
||||||
<circle cx="18" cy="12" r="2.5" fill="#FFFFFF"/>
|
<circle cx="18" cy="12" r="2.5" fill="#FFFFFF" />
|
||||||
<circle cx="18" cy="12" r="0.7" fill="#000080"/>
|
<circle cx="18" cy="12" r="0.7" fill="#000080" />
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
} @else {
|
} @else {
|
||||||
@@ -129,7 +131,10 @@
|
|||||||
@if (createClientForm.get('fullname')) {
|
@if (createClientForm.get('fullname')) {
|
||||||
<mat-form-field appearance="outline" class="form-field full-width">
|
<mat-form-field appearance="outline" class="form-field full-width">
|
||||||
<mat-label>
|
<mat-label>
|
||||||
{{ 'labels.inputs.' + getDateLabel(createClientForm.get('legalFormId')?.value, ['Name', 'Entity Name']) | translate }}
|
{{
|
||||||
|
'labels.inputs.' + getDateLabel(createClientForm.get('legalFormId')?.value, ['Name', 'Entity Name'])
|
||||||
|
| translate
|
||||||
|
}}
|
||||||
</mat-label>
|
</mat-label>
|
||||||
<input matInput required formControlName="fullname" />
|
<input matInput required formControlName="fullname" />
|
||||||
@if (createClientForm.controls.fullname.hasError('required')) {
|
@if (createClientForm.controls.fullname.hasError('required')) {
|
||||||
@@ -150,30 +155,39 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="verify-inline">
|
<div class="verify-inline">
|
||||||
@if (!sanctionsVerified && !sanctionsBlocked) {
|
@if (!sanctionsVerified && !sanctionsBlocked) {
|
||||||
<button mat-stroked-button color="primary" type="button" class="verify-name-btn"
|
<button
|
||||||
|
mat-stroked-button
|
||||||
|
color="primary"
|
||||||
|
type="button"
|
||||||
|
class="verify-name-btn"
|
||||||
[disabled]="readOnly"
|
[disabled]="readOnly"
|
||||||
(click)="verifySanctions()">
|
(click)="verifySanctions()"
|
||||||
|
>
|
||||||
<fa-icon icon="shield-alt" class="verify-name-icon"></fa-icon>
|
<fa-icon icon="shield-alt" class="verify-name-icon"></fa-icon>
|
||||||
Verify Entity
|
Verify Entity
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@if (sanctionsVerified) {
|
@if (sanctionsVerified) {
|
||||||
<span class="sanctions-citation">RBI KYC Master Direction (2016) — Section 51 & PMLA 2002</span>
|
<span class="sanctions-citation">RBI KYC Master Direction (2016) — Section 51 & PMLA 2002</span>
|
||||||
<span class="verify-status verified">
|
<span class="verify-status verified"> <fa-icon icon="check-circle"></fa-icon> Verified </span>
|
||||||
<fa-icon icon="check-circle"></fa-icon> Verified
|
<mat-icon
|
||||||
</span>
|
class="sanctions-info-icon"
|
||||||
<mat-icon class="sanctions-info-icon"
|
|
||||||
matTooltip="All customer names must be verified against the UN Security Council Consolidated List before account opening and periodically thereafter. Positive matches must be escalated to the Principal Officer immediately."
|
matTooltip="All customer names must be verified against the UN Security Council Consolidated List before account opening and periodically thereafter. Positive matches must be escalated to the Principal Officer immediately."
|
||||||
matTooltipClass="sanctions-tooltip">info</mat-icon>
|
matTooltipClass="sanctions-tooltip"
|
||||||
|
>info</mat-icon
|
||||||
|
>
|
||||||
}
|
}
|
||||||
@if (sanctionsBlocked) {
|
@if (sanctionsBlocked) {
|
||||||
<span class="sanctions-citation">RBI KYC Master Direction (2016) — Section 51 & PMLA 2002</span>
|
<span class="sanctions-citation">RBI KYC Master Direction (2016) — Section 51 & PMLA 2002</span>
|
||||||
<span class="verify-status blocked">
|
<span class="verify-status blocked">
|
||||||
<fa-icon icon="exclamation-triangle"></fa-icon> Sanctions Match
|
<fa-icon icon="exclamation-triangle"></fa-icon> Sanctions Match
|
||||||
</span>
|
</span>
|
||||||
<mat-icon class="sanctions-info-icon blocked-info"
|
<mat-icon
|
||||||
|
class="sanctions-info-icon blocked-info"
|
||||||
matTooltip="All customer names must be verified against the UN Security Council Consolidated List before account opening and periodically thereafter. Positive matches must be escalated to the Principal Officer immediately."
|
matTooltip="All customer names must be verified against the UN Security Council Consolidated List before account opening and periodically thereafter. Positive matches must be escalated to the Principal Officer immediately."
|
||||||
matTooltipClass="sanctions-tooltip">info</mat-icon>
|
matTooltipClass="sanctions-tooltip"
|
||||||
|
>info</mat-icon
|
||||||
|
>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -181,7 +195,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<!-- Person: Salutation + First / Middle / Last Name -->
|
<!-- Person: Salutation + First / Middle / Last Name -->
|
||||||
@if (createClientForm.get('firstname') || createClientForm.get('middlename') || createClientForm.get('lastname')) {
|
@if (
|
||||||
|
createClientForm.get('firstname') || createClientForm.get('middlename') || createClientForm.get('lastname')
|
||||||
|
) {
|
||||||
<div class="name-fields-row">
|
<div class="name-fields-row">
|
||||||
@if (createClientForm.get('salutationId') && salutationOptions?.length > 0) {
|
@if (createClientForm.get('salutationId') && salutationOptions?.length > 0) {
|
||||||
<mat-form-field appearance="outline" class="name-field salutation-field-wide">
|
<mat-form-field appearance="outline" class="name-field salutation-field-wide">
|
||||||
@@ -213,7 +229,10 @@
|
|||||||
<mat-label>{{ 'labels.inputs.Middle Name' | translate }}</mat-label>
|
<mat-label>{{ 'labels.inputs.Middle Name' | translate }}</mat-label>
|
||||||
<span matPrefix class="field-prefix-icon"><mat-icon>person_outline</mat-icon></span>
|
<span matPrefix class="field-prefix-icon"><mat-icon>person_outline</mat-icon></span>
|
||||||
<input matInput formControlName="middlename" />
|
<input matInput formControlName="middlename" />
|
||||||
@if (createClientForm.controls.middlename?.hasError('pattern') && createClientForm.controls.middlename?.touched) {
|
@if (
|
||||||
|
createClientForm.controls.middlename?.hasError('pattern') &&
|
||||||
|
createClientForm.controls.middlename?.touched
|
||||||
|
) {
|
||||||
<mat-error>Only letters, spaces, dots and hyphens allowed</mat-error>
|
<mat-error>Only letters, spaces, dots and hyphens allowed</mat-error>
|
||||||
}
|
}
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
@@ -243,30 +262,39 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="verify-inline">
|
<div class="verify-inline">
|
||||||
@if (!sanctionsVerified && !sanctionsBlocked) {
|
@if (!sanctionsVerified && !sanctionsBlocked) {
|
||||||
<button mat-stroked-button color="primary" type="button" class="verify-name-btn"
|
<button
|
||||||
|
mat-stroked-button
|
||||||
|
color="primary"
|
||||||
|
type="button"
|
||||||
|
class="verify-name-btn"
|
||||||
[disabled]="readOnly"
|
[disabled]="readOnly"
|
||||||
(click)="verifySanctions()">
|
(click)="verifySanctions()"
|
||||||
|
>
|
||||||
<fa-icon icon="shield-alt" class="verify-name-icon"></fa-icon>
|
<fa-icon icon="shield-alt" class="verify-name-icon"></fa-icon>
|
||||||
Verify Client
|
Verify Client
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@if (sanctionsVerified) {
|
@if (sanctionsVerified) {
|
||||||
<span class="sanctions-citation">RBI KYC Master Direction (2016) — Section 51 & PMLA 2002</span>
|
<span class="sanctions-citation">RBI KYC Master Direction (2016) — Section 51 & PMLA 2002</span>
|
||||||
<span class="verify-status verified">
|
<span class="verify-status verified"> <fa-icon icon="check-circle"></fa-icon> Verified </span>
|
||||||
<fa-icon icon="check-circle"></fa-icon> Verified
|
<mat-icon
|
||||||
</span>
|
class="sanctions-info-icon"
|
||||||
<mat-icon class="sanctions-info-icon"
|
|
||||||
matTooltip="All customer names must be verified against the UN Security Council Consolidated List before account opening and periodically thereafter. Positive matches must be escalated to the Principal Officer immediately."
|
matTooltip="All customer names must be verified against the UN Security Council Consolidated List before account opening and periodically thereafter. Positive matches must be escalated to the Principal Officer immediately."
|
||||||
matTooltipClass="sanctions-tooltip">info</mat-icon>
|
matTooltipClass="sanctions-tooltip"
|
||||||
|
>info</mat-icon
|
||||||
|
>
|
||||||
}
|
}
|
||||||
@if (sanctionsBlocked) {
|
@if (sanctionsBlocked) {
|
||||||
<span class="sanctions-citation">RBI KYC Master Direction (2016) — Section 51 & PMLA 2002</span>
|
<span class="sanctions-citation">RBI KYC Master Direction (2016) — Section 51 & PMLA 2002</span>
|
||||||
<span class="verify-status blocked">
|
<span class="verify-status blocked">
|
||||||
<fa-icon icon="exclamation-triangle"></fa-icon> Sanctions Match
|
<fa-icon icon="exclamation-triangle"></fa-icon> Sanctions Match
|
||||||
</span>
|
</span>
|
||||||
<mat-icon class="sanctions-info-icon blocked-info"
|
<mat-icon
|
||||||
|
class="sanctions-info-icon blocked-info"
|
||||||
matTooltip="All customer names must be verified against the UN Security Council Consolidated List before account opening and periodically thereafter. Positive matches must be escalated to the Principal Officer immediately."
|
matTooltip="All customer names must be verified against the UN Security Council Consolidated List before account opening and periodically thereafter. Positive matches must be escalated to the Principal Officer immediately."
|
||||||
matTooltipClass="sanctions-tooltip">info</mat-icon>
|
matTooltipClass="sanctions-tooltip"
|
||||||
|
>info</mat-icon
|
||||||
|
>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -278,10 +306,18 @@
|
|||||||
<mat-form-field appearance="outline" class="form-field" (click)="dateOfBirthDatePicker.open()">
|
<mat-form-field appearance="outline" class="form-field" (click)="dateOfBirthDatePicker.open()">
|
||||||
<mat-label>Date of Birth</mat-label>
|
<mat-label>Date of Birth</mat-label>
|
||||||
<span matPrefix class="field-prefix-icon"><mat-icon>calendar_today</mat-icon></span>
|
<span matPrefix class="field-prefix-icon"><mat-icon>calendar_today</mat-icon></span>
|
||||||
<input matInput required [max]="maxDate" [matDatepicker]="dateOfBirthDatePicker" formControlName="dateOfBirth" />
|
<input
|
||||||
|
matInput
|
||||||
|
required
|
||||||
|
[max]="maxDate"
|
||||||
|
[matDatepicker]="dateOfBirthDatePicker"
|
||||||
|
formControlName="dateOfBirth"
|
||||||
|
/>
|
||||||
<mat-datepicker-toggle matSuffix [for]="dateOfBirthDatePicker"></mat-datepicker-toggle>
|
<mat-datepicker-toggle matSuffix [for]="dateOfBirthDatePicker"></mat-datepicker-toggle>
|
||||||
<mat-datepicker #dateOfBirthDatePicker></mat-datepicker>
|
<mat-datepicker #dateOfBirthDatePicker></mat-datepicker>
|
||||||
@if (createClientForm.get('dateOfBirth')?.hasError('required') && createClientForm.get('dateOfBirth')?.touched) {
|
@if (
|
||||||
|
createClientForm.get('dateOfBirth')?.hasError('required') && createClientForm.get('dateOfBirth')?.touched
|
||||||
|
) {
|
||||||
<mat-error>Date of Birth is <strong>required</strong></mat-error>
|
<mat-error>Date of Birth is <strong>required</strong></mat-error>
|
||||||
}
|
}
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
@@ -324,7 +360,6 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Minor / Guardian Mapping (mandatory if age < 10) -->
|
<!-- Minor / Guardian Mapping (mandatory if age < 10) -->
|
||||||
@@ -341,9 +376,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="guardian-section__header-right">
|
<div class="guardian-section__header-right">
|
||||||
<div class="guardian-section__age-chips">
|
<div class="guardian-section__age-chips">
|
||||||
<span class="guardian-age-chip"><strong>{{ ageBreakdown.years }}</strong> yrs</span>
|
<span class="guardian-age-chip"
|
||||||
<span class="guardian-age-chip"><strong>{{ ageBreakdown.months }}</strong> mos</span>
|
><strong>{{ ageBreakdown.years }}</strong> yrs</span
|
||||||
<span class="guardian-age-chip"><strong>{{ ageBreakdown.days }}</strong> days</span>
|
>
|
||||||
|
<span class="guardian-age-chip"
|
||||||
|
><strong>{{ ageBreakdown.months }}</strong> mos</span
|
||||||
|
>
|
||||||
|
<span class="guardian-age-chip"
|
||||||
|
><strong>{{ ageBreakdown.days }}</strong> days</span
|
||||||
|
>
|
||||||
<span class="guardian-minor-badge">MINOR</span>
|
<span class="guardian-minor-badge">MINOR</span>
|
||||||
</div>
|
</div>
|
||||||
@if (!selectedGuardian && !guardianLinking) {
|
@if (!selectedGuardian && !guardianLinking) {
|
||||||
@@ -357,13 +398,14 @@
|
|||||||
|
|
||||||
<!-- Body -->
|
<!-- Body -->
|
||||||
<div class="guardian-section__body" formGroupName="guardianDetails">
|
<div class="guardian-section__body" formGroupName="guardianDetails">
|
||||||
|
|
||||||
<!-- Empty state: no guardian linked, not linking -->
|
<!-- Empty state: no guardian linked, not linking -->
|
||||||
@if (!selectedGuardian && !guardianLinking) {
|
@if (!selectedGuardian && !guardianLinking) {
|
||||||
<div class="guardian-empty guardian-empty--required">
|
<div class="guardian-empty guardian-empty--required">
|
||||||
<mat-icon class="guardian-empty__icon">person_off</mat-icon>
|
<mat-icon class="guardian-empty__icon">person_off</mat-icon>
|
||||||
<div class="guardian-empty__content">
|
<div class="guardian-empty__content">
|
||||||
<span class="guardian-empty__text">No guardian linked yet. Click <strong>"Link Guardian"</strong> to search and add.</span>
|
<span class="guardian-empty__text"
|
||||||
|
>No guardian linked yet. Click <strong>"Link Guardian"</strong> to search and add.</span
|
||||||
|
>
|
||||||
<span class="guardian-empty__required">Guardian is mandatory for minor accounts</span>
|
<span class="guardian-empty__required">Guardian is mandatory for minor accounts</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -377,22 +419,33 @@
|
|||||||
<mat-select required formControlName="guardianRelation">
|
<mat-select required formControlName="guardianRelation">
|
||||||
<mat-option value="FATHER"><mat-icon class="icon-option-icon">man</mat-icon> Father</mat-option>
|
<mat-option value="FATHER"><mat-icon class="icon-option-icon">man</mat-icon> Father</mat-option>
|
||||||
<mat-option value="MOTHER"><mat-icon class="icon-option-icon">woman</mat-icon> Mother</mat-option>
|
<mat-option value="MOTHER"><mat-icon class="icon-option-icon">woman</mat-icon> Mother</mat-option>
|
||||||
<mat-option value="LEGAL_GUARDIAN"><mat-icon class="icon-option-icon">gavel</mat-icon> Legal Guardian</mat-option>
|
<mat-option value="LEGAL_GUARDIAN"
|
||||||
<mat-option value="GRANDPARENT"><mat-icon class="icon-option-icon">elderly</mat-icon> Grandparent</mat-option>
|
><mat-icon class="icon-option-icon">gavel</mat-icon> Legal Guardian</mat-option
|
||||||
|
>
|
||||||
|
<mat-option value="GRANDPARENT"
|
||||||
|
><mat-icon class="icon-option-icon">elderly</mat-icon> Grandparent</mat-option
|
||||||
|
>
|
||||||
<mat-option value="OTHER"><mat-icon class="icon-option-icon">group</mat-icon> Other</mat-option>
|
<mat-option value="OTHER"><mat-icon class="icon-option-icon">group</mat-icon> Other</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<div class="guardian-search-wrapper guardian-search-col">
|
<div class="guardian-search-wrapper guardian-search-col">
|
||||||
<mat-form-field appearance="outline" class="guardian-search-field"
|
<mat-form-field
|
||||||
[class.guardian-search-disabled]="!createClientForm.get('guardianDetails.guardianRelation')?.value">
|
appearance="outline"
|
||||||
|
class="guardian-search-field"
|
||||||
|
[class.guardian-search-disabled]="!createClientForm.get('guardianDetails.guardianRelation')?.value"
|
||||||
|
>
|
||||||
<mat-label>Search Guardian by Name or Client ID</mat-label>
|
<mat-label>Search Guardian by Name or Client ID</mat-label>
|
||||||
<span matPrefix class="field-prefix-icon"><mat-icon>person_search</mat-icon></span>
|
<span matPrefix class="field-prefix-icon"><mat-icon>person_search</mat-icon></span>
|
||||||
<input matInput [value]="guardianSearchText"
|
<input
|
||||||
|
matInput
|
||||||
|
[value]="guardianSearchText"
|
||||||
(input)="onGuardianSearch($any($event.target).value)"
|
(input)="onGuardianSearch($any($event.target).value)"
|
||||||
(blur)="dismissGuardianSearch()"
|
(blur)="dismissGuardianSearch()"
|
||||||
[disabled]="!createClientForm.get('guardianDetails.guardianRelation')?.value"
|
[disabled]="!createClientForm.get('guardianDetails.guardianRelation')?.value"
|
||||||
placeholder="Select relationship first, then search..." autocomplete="off" />
|
placeholder="Select relationship first, then search..."
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
@if (guardianSearching) {
|
@if (guardianSearching) {
|
||||||
@@ -413,11 +466,17 @@
|
|||||||
<div class="guardian-result-item__info">
|
<div class="guardian-result-item__info">
|
||||||
<span class="guardian-result-item__name">{{ result.displayName }}</span>
|
<span class="guardian-result-item__name">{{ result.displayName }}</span>
|
||||||
<span class="guardian-result-item__meta">
|
<span class="guardian-result-item__meta">
|
||||||
ID: {{ result.id }} · A/C: {{ result.accountNumber }} · {{ result.officeName }}@if (result.dateOfBirth) { · DOB: {{ result.dateOfBirth | dateFormat }} }@if (result.fatherSpouseName) { · {{ result.fatherSpouseName }} }
|
ID: {{ result.id }} · A/C: {{ result.accountNumber }} ·
|
||||||
|
{{ result.officeName }}
|
||||||
|
@if (result.dateOfBirth) {
|
||||||
|
· DOB: {{ result.dateOfBirth | dateFormat }}
|
||||||
|
}
|
||||||
|
@if (result.fatherSpouseName) {
|
||||||
|
· {{ result.fatherSpouseName }}
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="guardian-result-item__status"
|
<span class="guardian-result-item__status" [class.active]="result.status?.value === 'Active'">
|
||||||
[class.active]="result.status?.value === 'Active'">
|
|
||||||
{{ result.status?.value }}
|
{{ result.status?.value }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -429,7 +488,13 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button mat-icon-button type="button" class="guardian-cancel-link" (click)="guardianLinking = false" matTooltip="Cancel">
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
type="button"
|
||||||
|
class="guardian-cancel-link"
|
||||||
|
(click)="guardianLinking = false"
|
||||||
|
matTooltip="Cancel"
|
||||||
|
>
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -453,8 +518,12 @@
|
|||||||
<span class="guardian-row__col guardian-row__col--photo">
|
<span class="guardian-row__col guardian-row__col--photo">
|
||||||
<div class="guardian-row__avatar" [class.has-photo]="selectedGuardian.profileImageUrl">
|
<div class="guardian-row__avatar" [class.has-photo]="selectedGuardian.profileImageUrl">
|
||||||
@if (selectedGuardian.profileImageUrl) {
|
@if (selectedGuardian.profileImageUrl) {
|
||||||
<img [src]="selectedGuardian.profileImageUrl" alt="Photo" class="avatar-photo guardian-row__zoomable"
|
<img
|
||||||
(click)="zoomGuardianImage(selectedGuardian.profileImageUrl, 'Guardian Photo')" />
|
[src]="selectedGuardian.profileImageUrl"
|
||||||
|
alt="Photo"
|
||||||
|
class="avatar-photo guardian-row__zoomable"
|
||||||
|
(click)="zoomGuardianImage(selectedGuardian.profileImageUrl, 'Guardian Photo')"
|
||||||
|
/>
|
||||||
} @else {
|
} @else {
|
||||||
<fa-icon icon="user-shield"></fa-icon>
|
<fa-icon icon="user-shield"></fa-icon>
|
||||||
}
|
}
|
||||||
@@ -470,26 +539,40 @@
|
|||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<span class="guardian-row__col guardian-row__col--rel">
|
<span class="guardian-row__col guardian-row__col--rel">
|
||||||
<span class="guardian-row__rel-badge">{{ createClientForm.get('guardianDetails.guardianRelation')?.value || '-' }}</span>
|
<span class="guardian-row__rel-badge">{{
|
||||||
|
createClientForm.get('guardianDetails.guardianRelation')?.value || '-'
|
||||||
|
}}</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="guardian-row__col guardian-row__col--cif">
|
<span class="guardian-row__col guardian-row__col--cif">
|
||||||
<span class="guardian-row__mono">{{ selectedGuardian.accountNo || selectedGuardian.accountNumber || '-' }}</span>
|
<span class="guardian-row__mono">{{
|
||||||
|
selectedGuardian.accountNo || selectedGuardian.accountNumber || '-'
|
||||||
|
}}</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="guardian-row__col guardian-row__col--status">
|
<span class="guardian-row__col guardian-row__col--status">
|
||||||
<span class="guardian-row__status-badge"
|
<span
|
||||||
[class.guardian-row__status-badge--active]="selectedGuardian.status?.value === 'Active'">
|
class="guardian-row__status-badge"
|
||||||
|
[class.guardian-row__status-badge--active]="selectedGuardian.status?.value === 'Active'"
|
||||||
|
>
|
||||||
{{ selectedGuardian.status?.value || '-' }}
|
{{ selectedGuardian.status?.value || '-' }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="guardian-row__col guardian-row__col--actions">
|
<span class="guardian-row__col guardian-row__col--actions">
|
||||||
<button mat-icon-button type="button" class="guardian-action-btn"
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
type="button"
|
||||||
|
class="guardian-action-btn"
|
||||||
(click)="guardianExpanded = !guardianExpanded"
|
(click)="guardianExpanded = !guardianExpanded"
|
||||||
[matTooltip]="guardianExpanded ? 'Collapse' : 'View Details'">
|
[matTooltip]="guardianExpanded ? 'Collapse' : 'View Details'"
|
||||||
|
>
|
||||||
<mat-icon>{{ guardianExpanded ? 'expand_less' : 'visibility' }}</mat-icon>
|
<mat-icon>{{ guardianExpanded ? 'expand_less' : 'visibility' }}</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button mat-icon-button type="button" class="guardian-action-btn guardian-action-btn--delete"
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
type="button"
|
||||||
|
class="guardian-action-btn guardian-action-btn--delete"
|
||||||
(click)="removeGuardian()"
|
(click)="removeGuardian()"
|
||||||
matTooltip="Delete">
|
matTooltip="Delete"
|
||||||
|
>
|
||||||
<mat-icon>delete</mat-icon>
|
<mat-icon>delete</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
@@ -506,16 +589,22 @@
|
|||||||
@if (selectedGuardian.panNumber) {
|
@if (selectedGuardian.panNumber) {
|
||||||
<div class="guardian-expand__item">
|
<div class="guardian-expand__item">
|
||||||
<span class="guardian-expand__label">PAN</span>
|
<span class="guardian-expand__label">PAN</span>
|
||||||
<span class="guardian-expand__value">{{ selectedGuardian.panNumber }}
|
<span class="guardian-expand__value"
|
||||||
@if (selectedGuardian.panVerified) { <mat-icon class="verify-tick-sm">check_circle</mat-icon> }
|
>{{ selectedGuardian.panNumber }}
|
||||||
|
@if (selectedGuardian.panVerified) {
|
||||||
|
<mat-icon class="verify-tick-sm">check_circle</mat-icon>
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (selectedGuardian.aadhaarMasked) {
|
@if (selectedGuardian.aadhaarMasked) {
|
||||||
<div class="guardian-expand__item">
|
<div class="guardian-expand__item">
|
||||||
<span class="guardian-expand__label">Aadhaar</span>
|
<span class="guardian-expand__label">Aadhaar</span>
|
||||||
<span class="guardian-expand__value">{{ selectedGuardian.aadhaarMasked }}
|
<span class="guardian-expand__value"
|
||||||
@if (selectedGuardian.aadhaarVerified) { <mat-icon class="verify-tick-sm">check_circle</mat-icon> }
|
>{{ selectedGuardian.aadhaarMasked }}
|
||||||
|
@if (selectedGuardian.aadhaarVerified) {
|
||||||
|
<mat-icon class="verify-tick-sm">check_circle</mat-icon>
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -535,8 +624,12 @@
|
|||||||
@if (selectedGuardian.signatureUrl) {
|
@if (selectedGuardian.signatureUrl) {
|
||||||
<div class="guardian-expand__sig">
|
<div class="guardian-expand__sig">
|
||||||
<span class="guardian-expand__label">Specimen Signature</span>
|
<span class="guardian-expand__label">Specimen Signature</span>
|
||||||
<img [src]="selectedGuardian.signatureUrl" alt="Signature" class="guardian-expand__sig-img guardian-row__zoomable"
|
<img
|
||||||
(click)="zoomGuardianImage(selectedGuardian.signatureUrl, 'Specimen Signature')" />
|
[src]="selectedGuardian.signatureUrl"
|
||||||
|
alt="Signature"
|
||||||
|
class="guardian-expand__sig-img guardian-row__zoomable"
|
||||||
|
(click)="zoomGuardianImage(selectedGuardian.signatureUrl, 'Specimen Signature')"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -549,7 +642,7 @@
|
|||||||
|
|
||||||
<!-- Non-Individual Details -->
|
<!-- Non-Individual Details -->
|
||||||
@if (createClientForm.get('clientNonPersonDetails')) {
|
@if (createClientForm.get('clientNonPersonDetails')) {
|
||||||
<div class="form-grid" formGroupName="clientNonPersonDetails" style="margin-top: 16px;">
|
<div class="form-grid" formGroupName="clientNonPersonDetails" style="margin-top: 16px">
|
||||||
<mat-form-field appearance="outline" class="form-field">
|
<mat-form-field appearance="outline" class="form-field">
|
||||||
<mat-label>Constitution Type</mat-label>
|
<mat-label>Constitution Type</mat-label>
|
||||||
<mat-select formControlName="constitutionId" required>
|
<mat-select formControlName="constitutionId" required>
|
||||||
@@ -607,7 +700,10 @@
|
|||||||
</h4>
|
</h4>
|
||||||
<div class="minor-info-bar">
|
<div class="minor-info-bar">
|
||||||
<fa-icon icon="info-circle" class="minor-info-icon"></fa-icon>
|
<fa-icon icon="info-circle" class="minor-info-icon"></fa-icon>
|
||||||
<span>Select registered clients as authorized signatories — as per Board Resolution / Partnership Deed. Max 10.</span>
|
<span
|
||||||
|
>Select registered clients as authorized signatories — as per Board Resolution / Partnership Deed. Max
|
||||||
|
10.</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Signatory List Table -->
|
<!-- Signatory List Table -->
|
||||||
@@ -638,27 +734,45 @@
|
|||||||
<span class="sig-table__col sig-table__col--name">
|
<span class="sig-table__col sig-table__col--name">
|
||||||
<strong>{{ sig.displayName }}</strong>
|
<strong>{{ sig.displayName }}</strong>
|
||||||
@if (sig._loading) {
|
@if (sig._loading) {
|
||||||
<mat-progress-spinner diameter="14" mode="indeterminate" class="sig-inline-spinner"></mat-progress-spinner>
|
<mat-progress-spinner
|
||||||
|
diameter="14"
|
||||||
|
mode="indeterminate"
|
||||||
|
class="sig-inline-spinner"
|
||||||
|
></mat-progress-spinner>
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
<span class="sig-table__col sig-table__col--id">{{ sig.cifNumber || sig.id }}</span>
|
<span class="sig-table__col sig-table__col--id">{{ sig.cifNumber || sig.id }}</span>
|
||||||
<span class="sig-table__col sig-table__col--pan">
|
<span class="sig-table__col sig-table__col--pan">
|
||||||
{{ sig.panNumber || '-' }}
|
{{ sig.panNumber || '-' }}
|
||||||
@if (sig.panVerified) { <mat-icon class="verify-tick-sm">check_circle</mat-icon> }
|
@if (sig.panVerified) {
|
||||||
|
<mat-icon class="verify-tick-sm">check_circle</mat-icon>
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
<span class="sig-table__col sig-table__col--din">
|
<span class="sig-table__col sig-table__col--din">
|
||||||
@if (sig.dinNumber) {
|
@if (sig.dinNumber) {
|
||||||
{{ sig.dinNumber }}
|
{{ sig.dinNumber }}
|
||||||
@if (sig.dinVerified) { <mat-icon class="verify-tick-sm">check_circle</mat-icon> }
|
@if (sig.dinVerified) {
|
||||||
@if (!sig.dinVerified) { <mat-icon class="verify-cross-sm">cancel</mat-icon> }
|
<mat-icon class="verify-tick-sm">check_circle</mat-icon>
|
||||||
|
}
|
||||||
|
@if (!sig.dinVerified) {
|
||||||
|
<mat-icon class="verify-cross-sm">cancel</mat-icon>
|
||||||
|
}
|
||||||
} @else {
|
} @else {
|
||||||
<button mat-stroked-button class="din-verify-btn" type="button" matTooltip="Verify DIN" (click)="openDinVerifyDialog(sig)">
|
<button
|
||||||
|
mat-stroked-button
|
||||||
|
class="din-verify-btn"
|
||||||
|
type="button"
|
||||||
|
matTooltip="Verify DIN"
|
||||||
|
(click)="openDinVerifyDialog(sig)"
|
||||||
|
>
|
||||||
<mat-icon class="din-verify-icon">badge</mat-icon> Verify DIN
|
<mat-icon class="din-verify-icon">badge</mat-icon> Verify DIN
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
<span class="sig-table__col sig-table__col--status">
|
<span class="sig-table__col sig-table__col--status">
|
||||||
<span class="sig-status-chip" [class.active]="sig.status?.value === 'Active'">{{ sig.status?.value || '-' }}</span>
|
<span class="sig-status-chip" [class.active]="sig.status?.value === 'Active'">{{
|
||||||
|
sig.status?.value || '-'
|
||||||
|
}}</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="sig-table__col sig-table__col--actions">
|
<span class="sig-table__col sig-table__col--actions">
|
||||||
<button mat-icon-button type="button" matTooltip="View Details" (click)="viewSignatoryDetails(sig)">
|
<button mat-icon-button type="button" matTooltip="View Details" (click)="viewSignatoryDetails(sig)">
|
||||||
@@ -680,10 +794,14 @@
|
|||||||
<mat-form-field appearance="outline" class="guardian-search-field">
|
<mat-form-field appearance="outline" class="guardian-search-field">
|
||||||
<mat-label>Add Signatory — Search by Name or Client ID</mat-label>
|
<mat-label>Add Signatory — Search by Name or Client ID</mat-label>
|
||||||
<span matPrefix class="field-prefix-icon"><mat-icon>person_add</mat-icon></span>
|
<span matPrefix class="field-prefix-icon"><mat-icon>person_add</mat-icon></span>
|
||||||
<input matInput [value]="signatorySearchText"
|
<input
|
||||||
|
matInput
|
||||||
|
[value]="signatorySearchText"
|
||||||
(input)="onSignatorySearch($any($event.target).value)"
|
(input)="onSignatorySearch($any($event.target).value)"
|
||||||
(blur)="dismissSignatorySearch()"
|
(blur)="dismissSignatorySearch()"
|
||||||
placeholder="Type name or client ID..." autocomplete="off" />
|
placeholder="Type name or client ID..."
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
@if (signatorySearching) {
|
@if (signatorySearching) {
|
||||||
<div class="guardian-results">
|
<div class="guardian-results">
|
||||||
@@ -700,9 +818,20 @@
|
|||||||
<div class="guardian-result-item__avatar"><fa-icon icon="user"></fa-icon></div>
|
<div class="guardian-result-item__avatar"><fa-icon icon="user"></fa-icon></div>
|
||||||
<div class="guardian-result-item__info">
|
<div class="guardian-result-item__info">
|
||||||
<span class="guardian-result-item__name">{{ result.displayName }}</span>
|
<span class="guardian-result-item__name">{{ result.displayName }}</span>
|
||||||
<span class="guardian-result-item__meta">ID: {{ result.id }} · A/C: {{ result.accountNumber }} · {{ result.officeName }}@if (result.dateOfBirth) { · DOB: {{ result.dateOfBirth | dateFormat }} }@if (result.fatherSpouseName) { · {{ result.fatherSpouseName }} }</span>
|
<span class="guardian-result-item__meta"
|
||||||
|
>ID: {{ result.id }} · A/C: {{ result.accountNumber }} ·
|
||||||
|
{{ result.officeName }}
|
||||||
|
@if (result.dateOfBirth) {
|
||||||
|
· DOB: {{ result.dateOfBirth | dateFormat }}
|
||||||
|
}
|
||||||
|
@if (result.fatherSpouseName) {
|
||||||
|
· {{ result.fatherSpouseName }}
|
||||||
|
}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="guardian-result-item__status" [class.active]="result.status?.value === 'Active'">{{ result.status?.value }}</span>
|
<span class="guardian-result-item__status" [class.active]="result.status?.value === 'Active'">{{
|
||||||
|
result.status?.value
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -728,7 +857,6 @@
|
|||||||
<textarea matInput formControlName="remarks" cdkTextareaAutosize cdkAutosizeMinRows="2"></textarea>
|
<textarea matInput formControlName="remarks" cdkTextareaAutosize cdkAutosizeMinRows="2"></textarea>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -737,9 +865,12 @@
|
|||||||
<h4 class="section-title">
|
<h4 class="section-title">
|
||||||
<fa-icon icon="mobile-alt" class="section-icon"></fa-icon>
|
<fa-icon icon="mobile-alt" class="section-icon"></fa-icon>
|
||||||
Contact Details
|
Contact Details
|
||||||
<mat-icon class="dip-info-icon"
|
<mat-icon
|
||||||
|
class="dip-info-icon"
|
||||||
matTooltip="Digital Intelligence Platform (DIP) refers to the fraud-monitoring and intelligence ecosystem created by the Department of Telecommunications (DoT)"
|
matTooltip="Digital Intelligence Platform (DIP) refers to the fraud-monitoring and intelligence ecosystem created by the Department of Telecommunications (DoT)"
|
||||||
matTooltipPosition="above">info</mat-icon>
|
matTooltipPosition="above"
|
||||||
|
>info</mat-icon
|
||||||
|
>
|
||||||
</h4>
|
</h4>
|
||||||
|
|
||||||
<div class="form-grid">
|
<div class="form-grid">
|
||||||
@@ -747,21 +878,35 @@
|
|||||||
<mat-form-field appearance="outline" class="form-field">
|
<mat-form-field appearance="outline" class="form-field">
|
||||||
<mat-label>{{ 'labels.inputs.Mobile No' | translate }}</mat-label>
|
<mat-label>{{ 'labels.inputs.Mobile No' | translate }}</mat-label>
|
||||||
<span matPrefix class="field-prefix-icon"><mat-icon>phone_android</mat-icon></span>
|
<span matPrefix class="field-prefix-icon"><mat-icon>phone_android</mat-icon></span>
|
||||||
<input matInput required type="text" formControlName="mobileNo" placeholder="e.g. 9876543210" maxlength="10"
|
<input
|
||||||
|
matInput
|
||||||
|
required
|
||||||
|
type="text"
|
||||||
|
formControlName="mobileNo"
|
||||||
|
placeholder="e.g. 9876543210"
|
||||||
|
maxlength="10"
|
||||||
(keypress)="$event.charCode >= 48 && $event.charCode <= 57 ? true : $event.preventDefault()"
|
(keypress)="$event.charCode >= 48 && $event.charCode <= 57 ? true : $event.preventDefault()"
|
||||||
(paste)="$event.preventDefault()" />
|
(paste)="$event.preventDefault()"
|
||||||
|
/>
|
||||||
@if (createClientForm.get('mobileNo')?.hasError('required') && createClientForm.get('mobileNo')?.touched) {
|
@if (createClientForm.get('mobileNo')?.hasError('required') && createClientForm.get('mobileNo')?.touched) {
|
||||||
<mat-error>Mobile number is <strong>required</strong></mat-error>
|
<mat-error>Mobile number is <strong>required</strong></mat-error>
|
||||||
} @else if (createClientForm.get('mobileNo')?.hasError('pattern') && createClientForm.get('mobileNo')?.touched) {
|
} @else if (
|
||||||
|
createClientForm.get('mobileNo')?.hasError('pattern') && createClientForm.get('mobileNo')?.touched
|
||||||
|
) {
|
||||||
<mat-error>Enter valid 10-digit number (starts with 6-9)</mat-error>
|
<mat-error>Enter valid 10-digit number (starts with 6-9)</mat-error>
|
||||||
}
|
}
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<div class="form-field mobile-verify-row">
|
<div class="form-field mobile-verify-row">
|
||||||
@if (!mobileVerified) {
|
@if (!mobileVerified) {
|
||||||
<button mat-stroked-button color="primary" type="button" class="verify-btn"
|
<button
|
||||||
|
mat-stroked-button
|
||||||
|
color="primary"
|
||||||
|
type="button"
|
||||||
|
class="verify-btn"
|
||||||
[disabled]="readOnly || createClientForm.get('mobileNo')?.value?.length !== 10"
|
[disabled]="readOnly || createClientForm.get('mobileNo')?.value?.length !== 10"
|
||||||
(click)="verifyWithDIP()">
|
(click)="verifyWithDIP()"
|
||||||
|
>
|
||||||
<fa-icon icon="shield-alt" class="m-r-10"></fa-icon>
|
<fa-icon icon="shield-alt" class="m-r-10"></fa-icon>
|
||||||
Verify with DIP
|
Verify with DIP
|
||||||
</button>
|
</button>
|
||||||
@@ -774,19 +919,33 @@
|
|||||||
<mat-form-field appearance="outline" class="form-field">
|
<mat-form-field appearance="outline" class="form-field">
|
||||||
<mat-label>Alternate Mobile No</mat-label>
|
<mat-label>Alternate Mobile No</mat-label>
|
||||||
<span matPrefix class="field-prefix-icon"><mat-icon>phone_android</mat-icon></span>
|
<span matPrefix class="field-prefix-icon"><mat-icon>phone_android</mat-icon></span>
|
||||||
<input matInput type="text" formControlName="alternateMobileNo" placeholder="e.g. 9876543210" maxlength="10"
|
<input
|
||||||
|
matInput
|
||||||
|
type="text"
|
||||||
|
formControlName="alternateMobileNo"
|
||||||
|
placeholder="e.g. 9876543210"
|
||||||
|
maxlength="10"
|
||||||
(keypress)="$event.charCode >= 48 && $event.charCode <= 57 ? true : $event.preventDefault()"
|
(keypress)="$event.charCode >= 48 && $event.charCode <= 57 ? true : $event.preventDefault()"
|
||||||
(paste)="$event.preventDefault()" />
|
(paste)="$event.preventDefault()"
|
||||||
@if (createClientForm.get('alternateMobileNo')?.hasError('pattern') && createClientForm.get('alternateMobileNo')?.touched) {
|
/>
|
||||||
|
@if (
|
||||||
|
createClientForm.get('alternateMobileNo')?.hasError('pattern') &&
|
||||||
|
createClientForm.get('alternateMobileNo')?.touched
|
||||||
|
) {
|
||||||
<mat-error>Enter valid 10-digit number (starts with 6-9)</mat-error>
|
<mat-error>Enter valid 10-digit number (starts with 6-9)</mat-error>
|
||||||
}
|
}
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<div class="form-field mobile-verify-row">
|
<div class="form-field mobile-verify-row">
|
||||||
@if (!alternateMobileVerified) {
|
@if (!alternateMobileVerified) {
|
||||||
<button mat-stroked-button color="primary" type="button" class="verify-btn"
|
<button
|
||||||
|
mat-stroked-button
|
||||||
|
color="primary"
|
||||||
|
type="button"
|
||||||
|
class="verify-btn"
|
||||||
[disabled]="readOnly || createClientForm.get('alternateMobileNo')?.value?.length !== 10"
|
[disabled]="readOnly || createClientForm.get('alternateMobileNo')?.value?.length !== 10"
|
||||||
(click)="verifyAlternateDIP()">
|
(click)="verifyAlternateDIP()"
|
||||||
|
>
|
||||||
<fa-icon icon="shield-alt" class="m-r-10"></fa-icon>
|
<fa-icon icon="shield-alt" class="m-r-10"></fa-icon>
|
||||||
Verify with DIP
|
Verify with DIP
|
||||||
</button>
|
</button>
|
||||||
@@ -800,21 +959,27 @@
|
|||||||
<mat-label>{{ 'labels.inputs.Email Address' | translate }}</mat-label>
|
<mat-label>{{ 'labels.inputs.Email Address' | translate }}</mat-label>
|
||||||
<span matPrefix class="field-prefix-icon"><mat-icon>email</mat-icon></span>
|
<span matPrefix class="field-prefix-icon"><mat-icon>email</mat-icon></span>
|
||||||
<input matInput required formControlName="emailAddress" placeholder="e.g. name@example.com" />
|
<input matInput required formControlName="emailAddress" placeholder="e.g. name@example.com" />
|
||||||
@if (createClientForm.get('emailAddress')?.hasError('required') && createClientForm.get('emailAddress')?.touched) {
|
@if (
|
||||||
|
createClientForm.get('emailAddress')?.hasError('required') && createClientForm.get('emailAddress')?.touched
|
||||||
|
) {
|
||||||
<mat-error>Email is <strong>required</strong></mat-error>
|
<mat-error>Email is <strong>required</strong></mat-error>
|
||||||
} @else if (createClientForm.get('emailAddress')?.invalid && createClientForm.get('emailAddress')?.touched) {
|
} @else if (createClientForm.get('emailAddress')?.invalid && createClientForm.get('emailAddress')?.touched) {
|
||||||
<mat-error>Enter a valid email (e.g. name@example.com)</mat-error>
|
<mat-error>Enter a valid email (e.g. name@example.com)</mat-error>
|
||||||
}
|
}
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
@if (createClientForm.get('legalFormId')?.value === LegalFormId.PERSON && maritalStatusOptions.length > 0 && !isMinor) {
|
@if (
|
||||||
|
createClientForm.get('legalFormId')?.value === LegalFormId.PERSON && maritalStatusOptions.length > 0 && !isMinor
|
||||||
|
) {
|
||||||
<mat-form-field appearance="outline" class="form-field">
|
<mat-form-field appearance="outline" class="form-field">
|
||||||
<mat-label>Marital Status</mat-label>
|
<mat-label>Marital Status</mat-label>
|
||||||
<mat-select formControlName="maritalStatusId">
|
<mat-select formControlName="maritalStatusId">
|
||||||
<mat-select-trigger>
|
<mat-select-trigger>
|
||||||
@if (getSelectedMaritalStatus()) {
|
@if (getSelectedMaritalStatus()) {
|
||||||
<span class="icon-option">
|
<span class="icon-option">
|
||||||
<mat-icon class="icon-option-icon">{{ getMaritalStatusIcon(getSelectedMaritalStatus().name) }}</mat-icon>
|
<mat-icon class="icon-option-icon">{{
|
||||||
|
getMaritalStatusIcon(getSelectedMaritalStatus().name)
|
||||||
|
}}</mat-icon>
|
||||||
{{ getSelectedMaritalStatus().name }}
|
{{ getSelectedMaritalStatus().name }}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
@@ -833,83 +998,249 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Section: Education & Social Details (Individual only) -->
|
||||||
|
@if (createClientForm.get('legalFormId')?.value === LegalFormId.PERSON) {
|
||||||
|
<div class="section-block">
|
||||||
|
<h4 class="section-title">
|
||||||
|
<fa-icon icon="book" class="section-icon"></fa-icon>
|
||||||
|
Education & Social Details
|
||||||
|
</h4>
|
||||||
|
<div class="form-grid">
|
||||||
|
<!-- Education Level (non-minor) -->
|
||||||
|
@if (!isMinor) {
|
||||||
|
<mat-form-field appearance="outline" class="form-field">
|
||||||
|
<mat-label>Education Level</mat-label>
|
||||||
|
<mat-select formControlName="educationLevelId">
|
||||||
|
<mat-select-trigger>
|
||||||
|
@if (getSelectedEducationLevel()) {
|
||||||
|
<span class="icon-option">
|
||||||
|
<mat-icon class="icon-option-icon">{{
|
||||||
|
getEducationLevelIcon(getSelectedEducationLevel().name)
|
||||||
|
}}</mat-icon>
|
||||||
|
{{ getSelectedEducationLevel().name }}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</mat-select-trigger>
|
||||||
|
@for (el of educationLevelOptions; track el) {
|
||||||
|
<mat-option [value]="el.id">
|
||||||
|
<span class="icon-option">
|
||||||
|
<mat-icon class="icon-option-icon">{{ getEducationLevelIcon(el.name) }}</mat-icon>
|
||||||
|
{{ el.name }}
|
||||||
|
</span>
|
||||||
|
</mat-option>
|
||||||
|
}
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<!-- Degree / Qualification (depends on Education Level) -->
|
||||||
|
<mat-form-field appearance="outline" class="form-field">
|
||||||
|
<mat-label>Degree / Qualification</mat-label>
|
||||||
|
<mat-select
|
||||||
|
formControlName="degreeQualificationId"
|
||||||
|
[placeholder]="getSelectedEducationLevel() ? 'Select Degree' : 'Select Education Level first'"
|
||||||
|
>
|
||||||
|
<mat-select-trigger>
|
||||||
|
@if (getSelectedDegreeQualification()) {
|
||||||
|
<span class="icon-option">
|
||||||
|
<mat-icon class="icon-option-icon">{{
|
||||||
|
getDegreeQualificationIcon(getSelectedDegreeQualification().name)
|
||||||
|
}}</mat-icon>
|
||||||
|
{{ getSelectedDegreeQualification().name }}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</mat-select-trigger>
|
||||||
|
@for (dq of filteredDegreeQualificationOptions; track dq) {
|
||||||
|
<mat-option [value]="dq.id">
|
||||||
|
<span class="icon-option">
|
||||||
|
<mat-icon class="icon-option-icon">{{ getDegreeQualificationIcon(dq.name) }}</mat-icon>
|
||||||
|
{{ dq.name }}
|
||||||
|
</span>
|
||||||
|
</mat-option>
|
||||||
|
}
|
||||||
|
@if (!getSelectedEducationLevel()) {
|
||||||
|
<mat-option disabled>
|
||||||
|
<em>Please select Education Level first</em>
|
||||||
|
</mat-option>
|
||||||
|
} @else if (filteredDegreeQualificationOptions.length === 0) {
|
||||||
|
<mat-option disabled>
|
||||||
|
<em>No options available</em>
|
||||||
|
</mat-option>
|
||||||
|
}
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
}
|
||||||
|
|
||||||
|
<!-- Religion -->
|
||||||
|
<mat-form-field appearance="outline" class="form-field">
|
||||||
|
<mat-label>Religion</mat-label>
|
||||||
|
<mat-select formControlName="religionId">
|
||||||
|
<mat-select-trigger>
|
||||||
|
@if (getSelectedReligion()) {
|
||||||
|
<span class="icon-option">
|
||||||
|
<mat-icon class="icon-option-icon">{{ getReligionIcon(getSelectedReligion().name) }}</mat-icon>
|
||||||
|
{{ getSelectedReligion().name }}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</mat-select-trigger>
|
||||||
|
@for (r of religionOptions; track r) {
|
||||||
|
<mat-option [value]="r.id">
|
||||||
|
<span class="icon-option">
|
||||||
|
<mat-icon class="icon-option-icon">{{ getReligionIcon(r.name) }}</mat-icon>
|
||||||
|
{{ r.name }}
|
||||||
|
</span>
|
||||||
|
</mat-option>
|
||||||
|
}
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<!-- Social Category -->
|
||||||
|
<mat-form-field appearance="outline" class="form-field">
|
||||||
|
<mat-label>Social Category</mat-label>
|
||||||
|
<mat-select formControlName="socialCategoryId">
|
||||||
|
<mat-select-trigger>
|
||||||
|
@if (getSelectedSocialCategory()) {
|
||||||
|
<span class="icon-option">
|
||||||
|
<mat-icon class="icon-option-icon">{{
|
||||||
|
getSocialCategoryIcon(getSelectedSocialCategory().name)
|
||||||
|
}}</mat-icon>
|
||||||
|
{{ getSelectedSocialCategory().name }}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</mat-select-trigger>
|
||||||
|
@for (sc of socialCategoryOptions; track sc) {
|
||||||
|
<mat-option [value]="sc.id">
|
||||||
|
<span class="icon-option">
|
||||||
|
<mat-icon class="icon-option-icon">{{ getSocialCategoryIcon(sc.name) }}</mat-icon>
|
||||||
|
{{ sc.name }}
|
||||||
|
</span>
|
||||||
|
</mat-option>
|
||||||
|
}
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<!-- Section: Financial & Classification (Individual only) -->
|
<!-- Section: Financial & Classification (Individual only) -->
|
||||||
@if (createClientForm.get('legalFormId')?.value === LegalFormId.PERSON) {
|
@if (createClientForm.get('legalFormId')?.value === LegalFormId.PERSON) {
|
||||||
<div class="section-block">
|
<div class="section-block">
|
||||||
<h4 class="section-title">
|
<h4 class="section-title">
|
||||||
<fa-icon icon="chart-line" class="section-icon"></fa-icon>
|
<fa-icon icon="chart-line" class="section-icon"></fa-icon>
|
||||||
Financial & Classification
|
Financial & Classification
|
||||||
</h4>
|
</h4>
|
||||||
<div class="form-grid">
|
<div class="form-grid">
|
||||||
|
<mat-form-field appearance="outline" class="form-field">
|
||||||
|
<mat-label>{{ 'labels.inputs.Occupation Category' | translate }}</mat-label>
|
||||||
<mat-form-field appearance="outline" class="form-field">
|
<mat-select formControlName="occupationCategoryId">
|
||||||
<mat-label>{{ 'labels.inputs.Occupation Category' | translate }}</mat-label>
|
<mat-select-trigger>
|
||||||
<mat-select formControlName="occupationCategoryId">
|
@if (getSelectedOccupationCategory()) {
|
||||||
<mat-select-trigger>
|
<span class="occ-option">
|
||||||
@if (getSelectedOccupationCategory()) {
|
<mat-icon class="occ-option-icon">{{
|
||||||
<span class="occ-option">
|
getOccupationCategoryIcon(getSelectedOccupationCategory().name)
|
||||||
<mat-icon class="occ-option-icon">{{ getOccupationCategoryIcon(getSelectedOccupationCategory().name) }}</mat-icon>
|
}}</mat-icon>
|
||||||
{{ getSelectedOccupationCategory().name }}
|
{{ getSelectedOccupationCategory().name }}
|
||||||
</span>
|
</span>
|
||||||
|
}
|
||||||
|
</mat-select-trigger>
|
||||||
|
@for (cat of occupationCategoryOptions; track cat) {
|
||||||
|
<mat-option [value]="cat.id">
|
||||||
|
<span class="occ-option">
|
||||||
|
<mat-icon class="occ-option-icon">{{ getOccupationCategoryIcon(cat.name) }}</mat-icon>
|
||||||
|
{{ cat.name }}
|
||||||
|
</span>
|
||||||
|
</mat-option>
|
||||||
}
|
}
|
||||||
</mat-select-trigger>
|
</mat-select>
|
||||||
@for (cat of occupationCategoryOptions; track cat) {
|
</mat-form-field>
|
||||||
<mat-option [value]="cat.id">
|
|
||||||
<span class="occ-option">
|
|
||||||
<mat-icon class="occ-option-icon">{{ getOccupationCategoryIcon(cat.name) }}</mat-icon>
|
|
||||||
{{ cat.name }}
|
|
||||||
</span>
|
|
||||||
</mat-option>
|
|
||||||
}
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<mat-form-field appearance="outline" class="form-field">
|
<mat-form-field appearance="outline" class="form-field">
|
||||||
<mat-label>{{ 'labels.inputs.Occupation' | translate }}</mat-label>
|
<mat-label>{{ 'labels.inputs.Occupation' | translate }}</mat-label>
|
||||||
<mat-select formControlName="occupationId">
|
<mat-select formControlName="occupationId">
|
||||||
<mat-select-trigger>
|
<mat-select-trigger>
|
||||||
@if (getSelectedOccupation()) {
|
@if (getSelectedOccupation()) {
|
||||||
<span class="occ-option">
|
<span class="occ-option">
|
||||||
<mat-icon class="occ-option-icon">{{ getOccupationIcon(getSelectedOccupation().name) }}</mat-icon>
|
<mat-icon class="occ-option-icon">{{ getOccupationIcon(getSelectedOccupation().name) }}</mat-icon>
|
||||||
{{ getSelectedOccupation().name }}
|
{{ getSelectedOccupation().name }}
|
||||||
</span>
|
</span>
|
||||||
|
}
|
||||||
|
</mat-select-trigger>
|
||||||
|
@for (occ of occupationOptions; track occ) {
|
||||||
|
<mat-option [value]="occ.id">
|
||||||
|
<span class="occ-option">
|
||||||
|
<mat-icon class="occ-option-icon">{{ getOccupationIcon(occ.name) }}</mat-icon>
|
||||||
|
{{ occ.name }}
|
||||||
|
</span>
|
||||||
|
</mat-option>
|
||||||
}
|
}
|
||||||
</mat-select-trigger>
|
</mat-select>
|
||||||
@for (occ of occupationOptions; track occ) {
|
</mat-form-field>
|
||||||
<mat-option [value]="occ.id">
|
|
||||||
<span class="occ-option">
|
<mat-form-field appearance="outline" class="form-field">
|
||||||
<mat-icon class="occ-option-icon">{{ getOccupationIcon(occ.name) }}</mat-icon>
|
<mat-label>Monthly Income</mat-label>
|
||||||
{{ occ.name }}
|
<span matPrefix class="rupee-prefix">₹</span>
|
||||||
</span>
|
<input matInput type="number" formControlName="monthlyIncome" min="0" />
|
||||||
</mat-option>
|
@if (
|
||||||
|
createClientForm.get('monthlyIncome')?.hasError('pattern') && createClientForm.get('monthlyIncome')?.touched
|
||||||
|
) {
|
||||||
|
<mat-error>Enter a valid amount</mat-error>
|
||||||
|
} @else if (
|
||||||
|
createClientForm.get('monthlyIncome')?.hasError('min') && createClientForm.get('monthlyIncome')?.touched
|
||||||
|
) {
|
||||||
|
<mat-error>Amount cannot be negative</mat-error>
|
||||||
}
|
}
|
||||||
</mat-select>
|
</mat-form-field>
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<mat-form-field appearance="outline" class="form-field">
|
<mat-form-field appearance="outline" class="form-field">
|
||||||
<mat-label>Monthly Income</mat-label>
|
<mat-label>Annual Turnover (Last FY)</mat-label>
|
||||||
<span matPrefix class="rupee-prefix">₹</span>
|
<span matPrefix class="rupee-prefix">₹</span>
|
||||||
<input matInput type="number" formControlName="monthlyIncome" min="0" />
|
<input matInput type="number" formControlName="annualTurnover" min="0" />
|
||||||
@if (createClientForm.get('monthlyIncome')?.hasError('pattern') && createClientForm.get('monthlyIncome')?.touched) {
|
@if (
|
||||||
<mat-error>Enter a valid amount</mat-error>
|
createClientForm.get('annualTurnover')?.hasError('pattern') &&
|
||||||
} @else if (createClientForm.get('monthlyIncome')?.hasError('min') && createClientForm.get('monthlyIncome')?.touched) {
|
createClientForm.get('annualTurnover')?.touched
|
||||||
<mat-error>Amount cannot be negative</mat-error>
|
) {
|
||||||
}
|
<mat-error>Enter a valid amount</mat-error>
|
||||||
</mat-form-field>
|
} @else if (
|
||||||
|
createClientForm.get('annualTurnover')?.hasError('min') && createClientForm.get('annualTurnover')?.touched
|
||||||
|
) {
|
||||||
|
<mat-error>Amount cannot be negative</mat-error>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="outline" class="form-field">
|
<mat-form-field appearance="outline" class="form-field">
|
||||||
<mat-label>Annual Turnover (Last FY)</mat-label>
|
<mat-label>Agriculture Income</mat-label>
|
||||||
<span matPrefix class="rupee-prefix">₹</span>
|
<span matPrefix class="rupee-prefix">₹</span>
|
||||||
<input matInput type="number" formControlName="annualTurnover" min="0" />
|
<input matInput type="number" formControlName="agricultureIncome" min="0" />
|
||||||
@if (createClientForm.get('annualTurnover')?.hasError('pattern') && createClientForm.get('annualTurnover')?.touched) {
|
@if (
|
||||||
<mat-error>Enter a valid amount</mat-error>
|
createClientForm.get('agricultureIncome')?.hasError('pattern') &&
|
||||||
} @else if (createClientForm.get('annualTurnover')?.hasError('min') && createClientForm.get('annualTurnover')?.touched) {
|
createClientForm.get('agricultureIncome')?.touched
|
||||||
<mat-error>Amount cannot be negative</mat-error>
|
) {
|
||||||
}
|
<mat-error>Enter a valid amount</mat-error>
|
||||||
</mat-form-field>
|
} @else if (
|
||||||
|
createClientForm.get('agricultureIncome')?.hasError('min') &&
|
||||||
|
createClientForm.get('agricultureIncome')?.touched
|
||||||
|
) {
|
||||||
|
<mat-error>Amount cannot be negative</mat-error>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline" class="form-field">
|
||||||
|
<mat-label>Non-Agriculture Income</mat-label>
|
||||||
|
<span matPrefix class="rupee-prefix">₹</span>
|
||||||
|
<input matInput type="number" formControlName="nonAgricultureIncome" min="0" />
|
||||||
|
@if (
|
||||||
|
createClientForm.get('nonAgricultureIncome')?.hasError('pattern') &&
|
||||||
|
createClientForm.get('nonAgricultureIncome')?.touched
|
||||||
|
) {
|
||||||
|
<mat-error>Enter a valid amount</mat-error>
|
||||||
|
} @else if (
|
||||||
|
createClientForm.get('nonAgricultureIncome')?.hasError('min') &&
|
||||||
|
createClientForm.get('nonAgricultureIncome')?.touched
|
||||||
|
) {
|
||||||
|
<mat-error>Amount cannot be negative</mat-error>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- submittedOnDate is set automatically via form default (business date) -->
|
<!-- submittedOnDate is set automatically via form default (business date) -->
|
||||||
|
|||||||
+208
-50
@@ -95,8 +95,8 @@ form {
|
|||||||
background: #f0f9ff;
|
background: #f0f9ff;
|
||||||
border: 1px solid #bae6fd;
|
border: 1px solid #bae6fd;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
margin-top: -8px;
|
margin-top: 12px;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.full-name-preview {
|
.full-name-preview {
|
||||||
@@ -408,7 +408,10 @@ form {
|
|||||||
.guardian-cancel-link {
|
.guardian-cancel-link {
|
||||||
color: #94a3b8 !important;
|
color: #94a3b8 !important;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
&:hover { color: #ef4444 !important; }
|
|
||||||
|
&:hover {
|
||||||
|
color: #ef4444 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ═══ Guardian Row Table ═══ */
|
/* ═══ Guardian Row Table ═══ */
|
||||||
@@ -437,7 +440,10 @@ form {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 10px 12px;
|
padding: 10px 12px;
|
||||||
transition: background 0.1s;
|
transition: background 0.1s;
|
||||||
&:hover { background: #f8fafc; }
|
|
||||||
|
&:hover {
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.guardian-row__col {
|
.guardian-row__col {
|
||||||
@@ -445,12 +451,33 @@ form {
|
|||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: #1e293b;
|
color: #1e293b;
|
||||||
|
|
||||||
&--photo { flex: 0 0 50px; }
|
&--photo {
|
||||||
&--name { flex: 1; min-width: 0; }
|
flex: 0 0 50px;
|
||||||
&--rel { flex: 0 0 120px; }
|
}
|
||||||
&--cif { flex: 0 0 130px; }
|
|
||||||
&--status { flex: 0 0 80px; }
|
&--name {
|
||||||
&--actions { flex: 0 0 110px; display: flex; gap: 2px; justify-content: flex-end; }
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--rel {
|
||||||
|
flex: 0 0 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--cif {
|
||||||
|
flex: 0 0 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--status {
|
||||||
|
flex: 0 0 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--actions {
|
||||||
|
flex: 0 0 110px;
|
||||||
|
display: flex;
|
||||||
|
gap: 2px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.guardian-row__avatar {
|
.guardian-row__avatar {
|
||||||
@@ -543,14 +570,22 @@ form {
|
|||||||
color: #64748b;
|
color: #64748b;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover mat-icon { color: #1074b9; }
|
&:hover mat-icon {
|
||||||
&--delete:hover mat-icon { color: #ef4444; }
|
color: #1074b9;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--delete:hover mat-icon {
|
||||||
|
color: #ef4444;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.guardian-row__zoomable {
|
.guardian-row__zoomable {
|
||||||
cursor: zoom-in;
|
cursor: zoom-in;
|
||||||
transition: transform 0.15s;
|
transition: transform 0.15s;
|
||||||
&:hover { transform: scale(1.05); }
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expandable detail panel */
|
/* Expandable detail panel */
|
||||||
@@ -558,12 +593,19 @@ form {
|
|||||||
border-top: 1px solid #e2e8f0;
|
border-top: 1px solid #e2e8f0;
|
||||||
background: #f8fafc;
|
background: #f8fafc;
|
||||||
padding: 16px 20px;
|
padding: 16px 20px;
|
||||||
animation: guardianSlideDown 0.2s ease-out;
|
animation: guardian-slide-down 0.2s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes guardianSlideDown {
|
@keyframes guardian-slide-down {
|
||||||
from { opacity: 0; max-height: 0; }
|
from {
|
||||||
to { opacity: 1; max-height: 500px; }
|
opacity: 0;
|
||||||
|
max-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
max-height: 500px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.guardian-expand__grid {
|
.guardian-expand__grid {
|
||||||
@@ -666,7 +708,9 @@ form {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.guardian-row__header { display: none; }
|
.guardian-row__header {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.guardian-row__data {
|
.guardian-row__data {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@@ -674,10 +718,23 @@ form {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.guardian-row__col {
|
.guardian-row__col {
|
||||||
&--photo { flex: 0 0 40px; }
|
&--photo {
|
||||||
&--name { flex: 1 1 200px; }
|
flex: 0 0 40px;
|
||||||
&--rel, &--cif, &--status { flex: 0 0 auto; }
|
}
|
||||||
&--actions { flex: 0 0 auto; }
|
|
||||||
|
&--name {
|
||||||
|
flex: 1 1 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--rel,
|
||||||
|
&--cif,
|
||||||
|
&--status {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--actions {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.guardian-expand__grid {
|
.guardian-expand__grid {
|
||||||
@@ -777,8 +834,13 @@ form {
|
|||||||
transition: background 0.1s;
|
transition: background 0.1s;
|
||||||
border-bottom: 1px solid #f1f5f9;
|
border-bottom: 1px solid #f1f5f9;
|
||||||
|
|
||||||
&:last-child { border-bottom: none; }
|
&:last-child {
|
||||||
&:hover { background: #f0f7ff; }
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #f0f7ff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.guardian-result-item__avatar {
|
.guardian-result-item__avatar {
|
||||||
@@ -882,7 +944,10 @@ form {
|
|||||||
|
|
||||||
.guardian-card__remove {
|
.guardian-card__remove {
|
||||||
color: #94a3b8 !important;
|
color: #94a3b8 !important;
|
||||||
&:hover { color: #ef4444 !important; }
|
|
||||||
|
&:hover {
|
||||||
|
color: #ef4444 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.guardian-card__body {
|
.guardian-card__body {
|
||||||
@@ -899,8 +964,13 @@ form {
|
|||||||
border-bottom: 1px solid #f1f5f9;
|
border-bottom: 1px solid #f1f5f9;
|
||||||
border-right: 1px solid #f1f5f9;
|
border-right: 1px solid #f1f5f9;
|
||||||
|
|
||||||
&:nth-child(2n) { border-right: none; }
|
&:nth-child(2n) {
|
||||||
&:nth-last-child(-n+2) { border-bottom: none; }
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-last-child(-n + 2) {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.guardian-card__label {
|
.guardian-card__label {
|
||||||
@@ -1069,10 +1139,22 @@ form {
|
|||||||
color: #0f172a;
|
color: #0f172a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row-micro td { background: #ecfdf5; }
|
.row-micro td {
|
||||||
.row-small td { background: #e0f2fe; }
|
background: #ecfdf5;
|
||||||
.row-medium td { background: #fffbeb; }
|
}
|
||||||
.row-large td { background: #f8fafc; color: #94a3b8; }
|
|
||||||
|
.row-small td {
|
||||||
|
background: #e0f2fe;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-medium td {
|
||||||
|
background: #fffbeb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-large td {
|
||||||
|
background: #f8fafc;
|
||||||
|
color: #94a3b8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.msme-dot {
|
.msme-dot {
|
||||||
@@ -1082,10 +1164,21 @@ form {
|
|||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
|
|
||||||
&.green { background: #10b981; }
|
&.green {
|
||||||
&.blue { background: #0ea5e9; }
|
background: #10b981;
|
||||||
&.amber { background: #f59e0b; }
|
}
|
||||||
&.gray { background: #cbd5e1; }
|
|
||||||
|
&.blue {
|
||||||
|
background: #0ea5e9;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.amber {
|
||||||
|
background: #f59e0b;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.gray {
|
||||||
|
background: #cbd5e1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.msme-class-table-footer {
|
.msme-class-table-footer {
|
||||||
@@ -1499,19 +1592,68 @@ form {
|
|||||||
border-bottom: 1px solid #f1f5f9;
|
border-bottom: 1px solid #f1f5f9;
|
||||||
transition: background 0.15s;
|
transition: background 0.15s;
|
||||||
|
|
||||||
&:last-child { border-bottom: none; }
|
&:last-child {
|
||||||
&:hover { background: #f8fafc; }
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sig-table__col {
|
.sig-table__col {
|
||||||
&--sno { flex: 0 0 32px; text-align: center; color: #94a3b8; font-size: 12px; }
|
&--sno {
|
||||||
&--photo { flex: 0 0 40px; }
|
flex: 0 0 32px;
|
||||||
&--name { flex: 1; font-size: 13px; display: flex; align-items: center; gap: 6px; }
|
text-align: center;
|
||||||
&--id { flex: 0 0 100px; font-size: 12px; color: #64748b; }
|
color: #94a3b8;
|
||||||
&--pan { flex: 0 0 120px; font-size: 12px; color: #1e293b; display: flex; align-items: center; gap: 3px; }
|
font-size: 12px;
|
||||||
&--din { flex: 0 0 140px; font-size: 12px; color: #1e293b; display: flex; align-items: center; gap: 3px; }
|
}
|
||||||
&--status { flex: 0 0 80px; }
|
|
||||||
&--actions { flex: 0 0 80px; display: flex; gap: 2px; }
|
&--photo {
|
||||||
|
flex: 0 0 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--name {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 13px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--id {
|
||||||
|
flex: 0 0 100px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--pan {
|
||||||
|
flex: 0 0 120px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #1e293b;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--din {
|
||||||
|
flex: 0 0 140px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #1e293b;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--status {
|
||||||
|
flex: 0 0 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--actions {
|
||||||
|
flex: 0 0 80px;
|
||||||
|
display: flex;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sig-table__avatar {
|
.sig-table__avatar {
|
||||||
@@ -1526,11 +1668,21 @@ form {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&.has-photo { padding: 0; }
|
&.has-photo {
|
||||||
.avatar-photo { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-photo {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sig-inline-spinner { display: inline-block; }
|
.sig-inline-spinner {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
.verify-tick-sm {
|
.verify-tick-sm {
|
||||||
font-size: 14px !important;
|
font-size: 14px !important;
|
||||||
@@ -1569,7 +1721,10 @@ form {
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #94a3b8;
|
color: #94a3b8;
|
||||||
&.active { color: #22c55e; }
|
|
||||||
|
&.active {
|
||||||
|
color: #22c55e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sig-action-icon {
|
.sig-action-icon {
|
||||||
@@ -1577,7 +1732,10 @@ form {
|
|||||||
width: 18px !important;
|
width: 18px !important;
|
||||||
height: 18px !important;
|
height: 18px !important;
|
||||||
color: #64748b;
|
color: #64748b;
|
||||||
&.remove { color: #ef4444; }
|
|
||||||
|
&.remove {
|
||||||
|
color: #ef4444;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sig-add-wrapper {
|
.sig-add-wrapper {
|
||||||
|
|||||||
+903
-164
File diff suppressed because it is too large
Load Diff
+417
-180
@@ -88,14 +88,18 @@
|
|||||||
}
|
}
|
||||||
@if (client?.dateOfBirth) {
|
@if (client?.dateOfBirth) {
|
||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">{{ client.legalFormId === LegalFormId.PERSON ? 'Date of Birth' : 'Incorporation Date' }}</span>
|
<span class="preview-label">{{
|
||||||
|
client.legalFormId === LegalFormId.PERSON ? 'Date of Birth' : 'Incorporation Date'
|
||||||
|
}}</span>
|
||||||
<span class="preview-value">{{ client.dateOfBirth | dateFormat }}</span>
|
<span class="preview-value">{{ client.dateOfBirth | dateFormat }}</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (client?.legalFormId === LegalFormId.PERSON && client?.genderId) {
|
@if (client?.legalFormId === LegalFormId.PERSON && client?.genderId) {
|
||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Gender</span>
|
<span class="preview-label">Gender</span>
|
||||||
<span class="preview-value">{{ client.genderId | find: clientTemplate.genderOptions : 'id' : 'name' }}</span>
|
<span class="preview-value">{{
|
||||||
|
client.genderId | find: clientTemplate.genderOptions : 'id' : 'name'
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (client?.legalFormId) {
|
@if (client?.legalFormId) {
|
||||||
@@ -107,13 +111,17 @@
|
|||||||
@if (client?.officeId) {
|
@if (client?.officeId) {
|
||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Office</span>
|
<span class="preview-label">Office</span>
|
||||||
<span class="preview-value">{{ client.officeId | find: clientTemplate.officeOptions : 'id' : 'name' }}</span>
|
<span class="preview-value">{{
|
||||||
|
client.officeId | find: clientTemplate.officeOptions : 'id' : 'name'
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (client?.staffId) {
|
@if (client?.staffId) {
|
||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Staff</span>
|
<span class="preview-label">Staff</span>
|
||||||
<span class="preview-value">{{ client.staffId | find: clientTemplate.staffOptions : 'id' : 'displayName' }}</span>
|
<span class="preview-value">{{
|
||||||
|
client.staffId | find: clientTemplate.staffOptions : 'id' : 'displayName'
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (client?.legalFormId === LegalFormId.PERSON) {
|
@if (client?.legalFormId === LegalFormId.PERSON) {
|
||||||
@@ -134,10 +142,42 @@
|
|||||||
<span class="preview-value">{{ client.maritalStatusId | find: maritalStatusOptions : 'id' : 'name' }}</span>
|
<span class="preview-value">{{ client.maritalStatusId | find: maritalStatusOptions : 'id' : 'name' }}</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@if (client?.educationLevelId) {
|
||||||
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Education Level</span>
|
||||||
|
<span class="preview-value">{{
|
||||||
|
client.educationLevelId | find: educationLevelOptions : 'id' : 'name'
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (client?.degreeQualificationId) {
|
||||||
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Degree / Qualification</span>
|
||||||
|
<span class="preview-value">{{
|
||||||
|
client.degreeQualificationId | find: degreeQualificationOptions : 'id' : 'name'
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (client?.religionId) {
|
||||||
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Religion</span>
|
||||||
|
<span class="preview-value">{{ client.religionId | find: religionOptions : 'id' : 'name' }}</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (client?.socialCategoryId) {
|
||||||
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Social Category</span>
|
||||||
|
<span class="preview-value">{{
|
||||||
|
client.socialCategoryId | find: socialCategoryOptions : 'id' : 'name'
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
@if (client?.salutationId) {
|
@if (client?.salutationId) {
|
||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Salutation</span>
|
<span class="preview-label">Salutation</span>
|
||||||
<span class="preview-value">{{ client.salutationId | find: clientTemplate.salutationOptions : 'id' : 'name' }}</span>
|
<span class="preview-value">{{
|
||||||
|
client.salutationId | find: clientTemplate.salutationOptions : 'id' : 'name'
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (client?.ageYears != null) {
|
@if (client?.ageYears != null) {
|
||||||
@@ -150,7 +190,11 @@
|
|||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Minor</span>
|
<span class="preview-label">Minor</span>
|
||||||
<span class="preview-value">
|
<span class="preview-value">
|
||||||
<span [class]="client.isMinor ? 'preview-badge preview-badge--danger' : 'preview-badge preview-badge--verified'">
|
<span
|
||||||
|
[class]="
|
||||||
|
client.isMinor ? 'preview-badge preview-badge--danger' : 'preview-badge preview-badge--verified'
|
||||||
|
"
|
||||||
|
>
|
||||||
{{ client.isMinor ? 'Yes (Age < 10)' : 'No' }}
|
{{ client.isMinor ? 'Yes (Age < 10)' : 'No' }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -172,13 +216,19 @@
|
|||||||
@if (client.clientNonPersonDetails.constitutionId) {
|
@if (client.clientNonPersonDetails.constitutionId) {
|
||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Constitution</span>
|
<span class="preview-label">Constitution</span>
|
||||||
<span class="preview-value">{{ client.clientNonPersonDetails.constitutionId | find: clientTemplate.clientNonPersonConstitutionOptions : 'id' : 'name' }}</span>
|
<span class="preview-value">{{
|
||||||
|
client.clientNonPersonDetails.constitutionId
|
||||||
|
| find: clientTemplate.clientNonPersonConstitutionOptions : 'id' : 'name'
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (client.clientNonPersonDetails.mainBusinessLineId) {
|
@if (client.clientNonPersonDetails.mainBusinessLineId) {
|
||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Main Business Line</span>
|
<span class="preview-label">Main Business Line</span>
|
||||||
<span class="preview-value">{{ client.clientNonPersonDetails.mainBusinessLineId | find: clientTemplate.clientNonPersonMainBusinessLineOptions : 'id' : 'name' }}</span>
|
<span class="preview-value">{{
|
||||||
|
client.clientNonPersonDetails.mainBusinessLineId
|
||||||
|
| find: clientTemplate.clientNonPersonMainBusinessLineOptions : 'id' : 'name'
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (client.clientNonPersonDetails.incorpNumber) {
|
@if (client.clientNonPersonDetails.incorpNumber) {
|
||||||
@@ -215,17 +265,15 @@
|
|||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">DIP Verification</span>
|
<span class="preview-label">DIP Verification</span>
|
||||||
<span class="preview-value">
|
<span class="preview-value">
|
||||||
<span [class]="client?.dipVerified ? 'preview-badge preview-badge--verified' : 'preview-badge preview-badge--pending'">
|
<span
|
||||||
|
[class]="
|
||||||
|
client?.dipVerified ? 'preview-badge preview-badge--verified' : 'preview-badge preview-badge--pending'
|
||||||
|
"
|
||||||
|
>
|
||||||
{{ client?.dipVerified ? 'Verified' : 'Pending' }}
|
{{ client?.dipVerified ? 'Verified' : 'Pending' }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@if (client?.dipLookupLogId) {
|
|
||||||
<div class="preview-field">
|
|
||||||
<span class="preview-label">DIP Lookup Log ID</span>
|
|
||||||
<span class="preview-value mono">{{ client.dipLookupLogId }}</span>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
@if (client?.alternateMobileNo) {
|
@if (client?.alternateMobileNo) {
|
||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Alternate Mobile No</span>
|
<span class="preview-label">Alternate Mobile No</span>
|
||||||
@@ -236,18 +284,18 @@
|
|||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Alternate DIP Verification</span>
|
<span class="preview-label">Alternate DIP Verification</span>
|
||||||
<span class="preview-value">
|
<span class="preview-value">
|
||||||
<span [class]="client?.alternateDipVerified ? 'preview-badge preview-badge--verified' : 'preview-badge preview-badge--pending'">
|
<span
|
||||||
|
[class]="
|
||||||
|
client?.alternateDipVerified
|
||||||
|
? 'preview-badge preview-badge--verified'
|
||||||
|
: 'preview-badge preview-badge--pending'
|
||||||
|
"
|
||||||
|
>
|
||||||
{{ client?.alternateDipVerified ? 'Verified' : 'Pending' }}
|
{{ client?.alternateDipVerified ? 'Verified' : 'Pending' }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (client?.alternateDipLookupLogId) {
|
|
||||||
<div class="preview-field">
|
|
||||||
<span class="preview-label">Alternate DIP Lookup Log ID</span>
|
|
||||||
<span class="preview-value mono">{{ client.alternateDipLookupLogId }}</span>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
@if (client?.emailAddress) {
|
@if (client?.emailAddress) {
|
||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Email Address</span>
|
<span class="preview-label">Email Address</span>
|
||||||
@@ -257,78 +305,103 @@
|
|||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Name Verification (Sanctions)</span>
|
<span class="preview-label">Name Verification (Sanctions)</span>
|
||||||
<span class="preview-value">
|
<span class="preview-value">
|
||||||
<span [class]="client?.nameVerified ? 'preview-badge preview-badge--verified' : 'preview-badge preview-badge--danger'">
|
<span
|
||||||
{{ client?.nameVerified ? 'Verified — Clear' : (client?.nameVerified === false ? 'Sanctions Match' : 'Pending') }}
|
[class]="
|
||||||
|
client?.nameVerified ? 'preview-badge preview-badge--verified' : 'preview-badge preview-badge--danger'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
client?.nameVerified
|
||||||
|
? 'Verified — Clear'
|
||||||
|
: client?.nameVerified === false
|
||||||
|
? 'Sanctions Match'
|
||||||
|
: 'Pending'
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@if (client?.screeningLogId) {
|
|
||||||
<div class="preview-field">
|
|
||||||
<span class="preview-label">Screening Log ID</span>
|
|
||||||
<span class="preview-value mono">{{ client.screeningLogId }}</span>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Financial & Classification (Individual only) -->
|
<!-- Financial & Classification (Individual only) -->
|
||||||
@if (client?.legalFormId !== 2) {
|
@if (client?.legalFormId !== 2) {
|
||||||
<div class="info-card">
|
<div class="info-card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<fa-icon icon="chart-line" class="card-icon"></fa-icon>
|
<fa-icon icon="chart-line" class="card-icon"></fa-icon>
|
||||||
<span>Financial & Classification</span>
|
<span>Financial & Classification</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="preview-grid">
|
<div class="preview-grid">
|
||||||
@if (client?.occupationCategoryId) {
|
@if (client?.occupationCategoryId) {
|
||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Occupation Category</span>
|
<span class="preview-label">Occupation Category</span>
|
||||||
<span class="preview-value">{{ client.occupationCategoryId | find: clientTemplate.occupationCategoryOptions : 'id' : 'name' }}</span>
|
<span class="preview-value">{{
|
||||||
</div>
|
client.occupationCategoryId | find: clientTemplate.occupationCategoryOptions : 'id' : 'name'
|
||||||
}
|
}}</span>
|
||||||
@if (client?.occupationId) {
|
</div>
|
||||||
<div class="preview-field">
|
}
|
||||||
<span class="preview-label">Occupation</span>
|
@if (client?.occupationId) {
|
||||||
<span class="preview-value">{{ client.occupationId | find: clientTemplate.occupationOptions : 'id' : 'name' }}</span>
|
<div class="preview-field">
|
||||||
</div>
|
<span class="preview-label">Occupation</span>
|
||||||
}
|
<span class="preview-value">{{
|
||||||
@if (client?.clientTypeId) {
|
client.occupationId | find: clientTemplate.occupationOptions : 'id' : 'name'
|
||||||
<div class="preview-field">
|
}}</span>
|
||||||
<span class="preview-label">Client Type</span>
|
</div>
|
||||||
<span class="preview-value">{{ client.clientTypeId | find: clientTemplate.clientTypeOptions : 'id' : 'name' }}</span>
|
}
|
||||||
</div>
|
@if (client?.clientTypeId) {
|
||||||
}
|
<div class="preview-field">
|
||||||
@if (client?.clientClassificationId) {
|
<span class="preview-label">Client Type</span>
|
||||||
<div class="preview-field">
|
<span class="preview-value">{{
|
||||||
<span class="preview-label">Client Classification</span>
|
client.clientTypeId | find: clientTemplate.clientTypeOptions : 'id' : 'name'
|
||||||
<span class="preview-value">{{ client.clientClassificationId | find: clientTemplate.clientClassificationOptions : 'id' : 'name' }}</span>
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (client?.monthlyIncome) {
|
@if (client?.clientClassificationId) {
|
||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Monthly Income</span>
|
<span class="preview-label">Client Classification</span>
|
||||||
<span class="preview-value">₹ {{ client.monthlyIncome | number }}</span>
|
<span class="preview-value">{{
|
||||||
</div>
|
client.clientClassificationId | find: clientTemplate.clientClassificationOptions : 'id' : 'name'
|
||||||
}
|
}}</span>
|
||||||
@if (client?.annualTurnover) {
|
</div>
|
||||||
<div class="preview-field">
|
}
|
||||||
<span class="preview-label">Annual Turnover</span>
|
@if (client?.monthlyIncome) {
|
||||||
<span class="preview-value">₹ {{ client.annualTurnover | number }}</span>
|
<div class="preview-field">
|
||||||
</div>
|
<span class="preview-label">Monthly Income</span>
|
||||||
}
|
<span class="preview-value">₹ {{ client.monthlyIncome | number }}</span>
|
||||||
@if (!client?.occupationCategoryId && !client?.occupationId && !client?.clientTypeId && !client?.clientClassificationId && !client?.monthlyIncome && !client?.annualTurnover) {
|
</div>
|
||||||
<div class="preview-field full-width">
|
}
|
||||||
<span class="preview-value no-data">No classification data provided</span>
|
@if (client?.annualTurnover) {
|
||||||
</div>
|
<div class="preview-field">
|
||||||
}
|
<span class="preview-label">Annual Turnover</span>
|
||||||
|
<span class="preview-value">₹ {{ client.annualTurnover | number }}</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (
|
||||||
|
!client?.occupationCategoryId &&
|
||||||
|
!client?.occupationId &&
|
||||||
|
!client?.clientTypeId &&
|
||||||
|
!client?.clientClassificationId &&
|
||||||
|
!client?.monthlyIncome &&
|
||||||
|
!client?.annualTurnover
|
||||||
|
) {
|
||||||
|
<div class="preview-field full-width">
|
||||||
|
<span class="preview-value no-data">No classification data provided</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- KYC Details -->
|
<!-- KYC Details -->
|
||||||
@if (kycData?.panNumber || kycData?.aadhaarNumberMasked || kycData?.gstinNumber || kycData?.enterprisePan || kycData?.cinNumber) {
|
@if (
|
||||||
|
kycData?.panNumber ||
|
||||||
|
kycData?.aadhaarNumberMasked ||
|
||||||
|
kycData?.gstinNumber ||
|
||||||
|
kycData?.enterprisePan ||
|
||||||
|
kycData?.cinNumber
|
||||||
|
) {
|
||||||
<div class="info-card">
|
<div class="info-card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<fa-icon icon="fingerprint" class="card-icon"></fa-icon>
|
<fa-icon icon="fingerprint" class="card-icon"></fa-icon>
|
||||||
@@ -391,9 +464,13 @@
|
|||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Risk Category</span>
|
<span class="preview-label">Risk Category</span>
|
||||||
<span class="preview-value">
|
<span class="preview-value">
|
||||||
@if (kycData.riskCategory === 1) { Low Risk }
|
@if (kycData.riskCategory === 1) {
|
||||||
@else if (kycData.riskCategory === 2) { Medium Risk }
|
Low Risk
|
||||||
@else if (kycData.riskCategory === 3) { High Risk }
|
} @else if (kycData.riskCategory === 2) {
|
||||||
|
Medium Risk
|
||||||
|
} @else if (kycData.riskCategory === 3) {
|
||||||
|
High Risk
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -414,7 +491,7 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<fa-icon icon="user-shield" class="card-icon"></fa-icon>
|
<fa-icon icon="user-shield" class="card-icon"></fa-icon>
|
||||||
<span>Guardian Details</span>
|
<span>Guardian Details</span>
|
||||||
<span class="preview-badge preview-badge--info" style="margin-left:auto">Minor</span>
|
<span class="preview-badge preview-badge--info" style="margin-left: auto">Minor</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="preview-grid">
|
<div class="preview-grid">
|
||||||
@@ -450,7 +527,13 @@
|
|||||||
<div class="preview-field">
|
<div class="preview-field">
|
||||||
<span class="preview-label">Status</span>
|
<span class="preview-label">Status</span>
|
||||||
<span class="preview-value">
|
<span class="preview-value">
|
||||||
<span [class]="guardian.status?.value === 'Active' ? 'preview-badge preview-badge--verified' : 'preview-badge preview-badge--pending'">
|
<span
|
||||||
|
[class]="
|
||||||
|
guardian.status?.value === 'Active'
|
||||||
|
? 'preview-badge preview-badge--verified'
|
||||||
|
: 'preview-badge preview-badge--pending'
|
||||||
|
"
|
||||||
|
>
|
||||||
{{ guardian.status.value }}
|
{{ guardian.status.value }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -524,7 +607,12 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@if (!addressData.permanent?.addressLine1 && !addressData.current?.addressLine1 && !addressData.office?.addressLine1 && !addressData.correspondence?.addressLine1) {
|
@if (
|
||||||
|
!addressData.permanent?.addressLine1 &&
|
||||||
|
!addressData.current?.addressLine1 &&
|
||||||
|
!addressData.office?.addressLine1 &&
|
||||||
|
!addressData.correspondence?.addressLine1
|
||||||
|
) {
|
||||||
<div class="preview-field full-width">
|
<div class="preview-field full-width">
|
||||||
<span class="preview-value no-data">No address data provided</span>
|
<span class="preview-value no-data">No address data provided</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -563,40 +651,76 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="preview-grid">
|
<div class="preview-grid">
|
||||||
@if (entityClassificationData.msme.udyamRegistrationNumber) {
|
@if (entityClassificationData.msme.udyamRegistrationNumber) {
|
||||||
<div class="preview-field"><span class="preview-label">Udyam Registration No.</span><span class="preview-value mono">{{ entityClassificationData.msme.udyamRegistrationNumber }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Udyam Registration No.</span
|
||||||
|
><span class="preview-value mono">{{ entityClassificationData.msme.udyamRegistrationNumber }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.msme.msmeClassification) {
|
@if (entityClassificationData.msme.msmeClassification) {
|
||||||
<div class="preview-field"><span class="preview-label">MSME Classification</span><span class="preview-value">{{ entityClassificationData.msme.msmeClassification }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">MSME Classification</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.msme.msmeClassification }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.msme.enterpriseType) {
|
@if (entityClassificationData.msme.enterpriseType) {
|
||||||
<div class="preview-field"><span class="preview-label">Enterprise Type</span><span class="preview-value">{{ entityClassificationData.msme.enterpriseType }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Enterprise Type</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.msme.enterpriseType }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.msme.nicActivityCode) {
|
@if (entityClassificationData.msme.nicActivityCode) {
|
||||||
<div class="preview-field"><span class="preview-label">NIC Activity Code</span><span class="preview-value mono">{{ entityClassificationData.msme.nicActivityCode }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">NIC Activity Code</span
|
||||||
|
><span class="preview-value mono">{{ entityClassificationData.msme.nicActivityCode }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.msme.annualTurnover) {
|
@if (entityClassificationData.msme.annualTurnover) {
|
||||||
<div class="preview-field"><span class="preview-label">Annual Turnover</span><span class="preview-value">₹ {{ entityClassificationData.msme.annualTurnover }} Cr</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Annual Turnover</span
|
||||||
|
><span class="preview-value">₹ {{ entityClassificationData.msme.annualTurnover }} Cr</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.msme.investmentPlantMachinery) {
|
@if (entityClassificationData.msme.investmentPlantMachinery) {
|
||||||
<div class="preview-field"><span class="preview-label">Investment (Plant & Machinery)</span><span class="preview-value">₹ {{ entityClassificationData.msme.investmentPlantMachinery }} Cr</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Investment (Plant & Machinery)</span
|
||||||
|
><span class="preview-value">₹ {{ entityClassificationData.msme.investmentPlantMachinery }} Cr</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.msme.financialYearAssessment) {
|
@if (entityClassificationData.msme.financialYearAssessment) {
|
||||||
<div class="preview-field"><span class="preview-label">FY of Assessment</span><span class="preview-value">{{ entityClassificationData.msme.financialYearAssessment }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">FY of Assessment</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.msme.financialYearAssessment }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.msme.socialCategoryOwner) {
|
@if (entityClassificationData.msme.socialCategoryOwner) {
|
||||||
<div class="preview-field"><span class="preview-label">Social Category</span><span class="preview-value">{{ entityClassificationData.msme.socialCategoryOwner }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Social Category</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.msme.socialCategoryOwner }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.msme.genderPrimaryOwner) {
|
@if (entityClassificationData.msme.genderPrimaryOwner) {
|
||||||
<div class="preview-field"><span class="preview-label">Gender of Owner</span><span class="preview-value">{{ entityClassificationData.msme.genderPrimaryOwner }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Gender of Owner</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.msme.genderPrimaryOwner }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.msme.noOfEmployees) {
|
@if (entityClassificationData.msme.noOfEmployees) {
|
||||||
<div class="preview-field"><span class="preview-label">No. of Employees</span><span class="preview-value">{{ entityClassificationData.msme.noOfEmployees }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">No. of Employees</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.msme.noOfEmployees }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.msme.womenLedEnterprise) {
|
@if (entityClassificationData.msme.womenLedEnterprise) {
|
||||||
<div class="preview-field"><span class="preview-label">Women-led Enterprise</span><span class="preview-value"><span class="preview-badge preview-badge--verified">Yes</span></span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Women-led Enterprise</span
|
||||||
|
><span class="preview-value"><span class="preview-badge preview-badge--verified">Yes</span></span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.msme.divyangPwdOwned) {
|
@if (entityClassificationData.msme.divyangPwdOwned) {
|
||||||
<div class="preview-field"><span class="preview-label">Divyang (PWD) Owned</span><span class="preview-value"><span class="preview-badge preview-badge--verified">Yes</span></span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Divyang (PWD) Owned</span
|
||||||
|
><span class="preview-value"><span class="preview-badge preview-badge--verified">Yes</span></span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -613,19 +737,34 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="preview-grid">
|
<div class="preview-grid">
|
||||||
@if (entityClassificationData.startup.dpiitRecognitionNumber) {
|
@if (entityClassificationData.startup.dpiitRecognitionNumber) {
|
||||||
<div class="preview-field"><span class="preview-label">DPIIT Recognition No.</span><span class="preview-value mono">{{ entityClassificationData.startup.dpiitRecognitionNumber }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">DPIIT Recognition No.</span
|
||||||
|
><span class="preview-value mono">{{ entityClassificationData.startup.dpiitRecognitionNumber }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.startup.entityStage) {
|
@if (entityClassificationData.startup.entityStage) {
|
||||||
<div class="preview-field"><span class="preview-label">Entity Stage</span><span class="preview-value">{{ entityClassificationData.startup.entityStage }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Entity Stage</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.startup.entityStage }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.startup.sectorAsDpiit) {
|
@if (entityClassificationData.startup.sectorAsDpiit) {
|
||||||
<div class="preview-field"><span class="preview-label">Sector (DPIIT)</span><span class="preview-value">{{ entityClassificationData.startup.sectorAsDpiit }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Sector (DPIIT)</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.startup.sectorAsDpiit }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.startup.taxExemption80iac) {
|
@if (entityClassificationData.startup.taxExemption80iac) {
|
||||||
<div class="preview-field"><span class="preview-label">80IAC Tax Exemption</span><span class="preview-value"><span class="preview-badge preview-badge--verified">Yes</span></span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">80IAC Tax Exemption</span
|
||||||
|
><span class="preview-value"><span class="preview-badge preview-badge--verified">Yes</span></span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.startup.pslLoanLimit) {
|
@if (entityClassificationData.startup.pslLoanLimit) {
|
||||||
<div class="preview-field"><span class="preview-label">PSL Loan Limit</span><span class="preview-value">₹ {{ entityClassificationData.startup.pslLoanLimit | number }} Cr</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">PSL Loan Limit</span
|
||||||
|
><span class="preview-value">₹ {{ entityClassificationData.startup.pslLoanLimit | number }} Cr</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -642,22 +781,40 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="preview-grid">
|
<div class="preview-grid">
|
||||||
@if (entityClassificationData.mudra.mudraCategory) {
|
@if (entityClassificationData.mudra.mudraCategory) {
|
||||||
<div class="preview-field"><span class="preview-label">Mudra Category</span><span class="preview-value">{{ entityClassificationData.mudra.mudraCategory }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Mudra Category</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.mudra.mudraCategory }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.mudra.mudraLoanAccountNo) {
|
@if (entityClassificationData.mudra.mudraLoanAccountNo) {
|
||||||
<div class="preview-field"><span class="preview-label">Loan Account No.</span><span class="preview-value mono">{{ entityClassificationData.mudra.mudraLoanAccountNo }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Loan Account No.</span
|
||||||
|
><span class="preview-value mono">{{ entityClassificationData.mudra.mudraLoanAccountNo }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.mudra.sanctionedAmount) {
|
@if (entityClassificationData.mudra.sanctionedAmount) {
|
||||||
<div class="preview-field"><span class="preview-label">Sanctioned Amount</span><span class="preview-value">₹ {{ entityClassificationData.mudra.sanctionedAmount | number }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Sanctioned Amount</span
|
||||||
|
><span class="preview-value">₹ {{ entityClassificationData.mudra.sanctionedAmount | number }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.mudra.lendingInstitutionName) {
|
@if (entityClassificationData.mudra.lendingInstitutionName) {
|
||||||
<div class="preview-field"><span class="preview-label">Lending Institution</span><span class="preview-value">{{ entityClassificationData.mudra.lendingInstitutionName }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Lending Institution</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.mudra.lendingInstitutionName }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.mudra.repaymentStatus) {
|
@if (entityClassificationData.mudra.repaymentStatus) {
|
||||||
<div class="preview-field"><span class="preview-label">Repayment Status</span><span class="preview-value">{{ entityClassificationData.mudra.repaymentStatus }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Repayment Status</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.mudra.repaymentStatus }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.mudra.npaFlag) {
|
@if (entityClassificationData.mudra.npaFlag) {
|
||||||
<div class="preview-field"><span class="preview-label">NPA Flag</span><span class="preview-value"><span class="preview-badge preview-badge--danger">NPA</span></span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">NPA Flag</span
|
||||||
|
><span class="preview-value"><span class="preview-badge preview-badge--danger">NPA</span></span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -674,19 +831,36 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="preview-grid">
|
<div class="preview-grid">
|
||||||
@if (entityClassificationData.eou.eouRegistrationNumber) {
|
@if (entityClassificationData.eou.eouRegistrationNumber) {
|
||||||
<div class="preview-field"><span class="preview-label">EOU Registration No.</span><span class="preview-value mono">{{ entityClassificationData.eou.eouRegistrationNumber }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">EOU Registration No.</span
|
||||||
|
><span class="preview-value mono">{{ entityClassificationData.eou.eouRegistrationNumber }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.eou.registeredDcZone) {
|
@if (entityClassificationData.eou.registeredDcZone) {
|
||||||
<div class="preview-field"><span class="preview-label">Registered DC Zone</span><span class="preview-value">{{ entityClassificationData.eou.registeredDcZone }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Registered DC Zone</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.eou.registeredDcZone }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.eou.gstinEou) {
|
@if (entityClassificationData.eou.gstinEou) {
|
||||||
<div class="preview-field"><span class="preview-label">GSTIN (EOU)</span><span class="preview-value mono">{{ entityClassificationData.eou.gstinEou }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">GSTIN (EOU)</span
|
||||||
|
><span class="preview-value mono">{{ entityClassificationData.eou.gstinEou }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.eou.annualExportObligation) {
|
@if (entityClassificationData.eou.annualExportObligation) {
|
||||||
<div class="preview-field"><span class="preview-label">Export Obligation</span><span class="preview-value">₹ {{ entityClassificationData.eou.annualExportObligation | number }} Cr</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Export Obligation</span
|
||||||
|
><span class="preview-value"
|
||||||
|
>₹ {{ entityClassificationData.eou.annualExportObligation | number }} Cr</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.eou.adCategoryBankCode) {
|
@if (entityClassificationData.eou.adCategoryBankCode) {
|
||||||
<div class="preview-field"><span class="preview-label">AD Bank Code</span><span class="preview-value mono">{{ entityClassificationData.eou.adCategoryBankCode }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">AD Bank Code</span
|
||||||
|
><span class="preview-value mono">{{ entityClassificationData.eou.adCategoryBankCode }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -703,22 +877,40 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="preview-grid">
|
<div class="preview-grid">
|
||||||
@if (entityClassificationData.importexport.iecCode) {
|
@if (entityClassificationData.importexport.iecCode) {
|
||||||
<div class="preview-field"><span class="preview-label">IEC Code</span><span class="preview-value mono">{{ entityClassificationData.importexport.iecCode }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">IEC Code</span
|
||||||
|
><span class="preview-value mono">{{ entityClassificationData.importexport.iecCode }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.importexport.iecStatus) {
|
@if (entityClassificationData.importexport.iecStatus) {
|
||||||
<div class="preview-field"><span class="preview-label">IEC Status</span><span class="preview-value">{{ entityClassificationData.importexport.iecStatus }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">IEC Status</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.importexport.iecStatus }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.importexport.tradeType) {
|
@if (entityClassificationData.importexport.tradeType) {
|
||||||
<div class="preview-field"><span class="preview-label">Trade Type</span><span class="preview-value">{{ entityClassificationData.importexport.tradeType }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Trade Type</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.importexport.tradeType }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.importexport.primaryHsCode) {
|
@if (entityClassificationData.importexport.primaryHsCode) {
|
||||||
<div class="preview-field"><span class="preview-label">Primary HS Code</span><span class="preview-value mono">{{ entityClassificationData.importexport.primaryHsCode }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Primary HS Code</span
|
||||||
|
><span class="preview-value mono">{{ entityClassificationData.importexport.primaryHsCode }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.importexport.eefcAccountRequired) {
|
@if (entityClassificationData.importexport.eefcAccountRequired) {
|
||||||
<div class="preview-field"><span class="preview-label">EEFC Account</span><span class="preview-value"><span class="preview-badge preview-badge--verified">Required</span></span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">EEFC Account</span
|
||||||
|
><span class="preview-value"><span class="preview-badge preview-badge--verified">Required</span></span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.importexport.femaDeclarationObtained) {
|
@if (entityClassificationData.importexport.femaDeclarationObtained) {
|
||||||
<div class="preview-field"><span class="preview-label">FEMA Declaration</span><span class="preview-value"><span class="preview-badge preview-badge--verified">Obtained</span></span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">FEMA Declaration</span
|
||||||
|
><span class="preview-value"><span class="preview-badge preview-badge--verified">Obtained</span></span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -735,22 +927,40 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="preview-grid">
|
<div class="preview-grid">
|
||||||
@if (entityClassificationData.psl.pslCategory) {
|
@if (entityClassificationData.psl.pslCategory) {
|
||||||
<div class="preview-field"><span class="preview-label">PSL Category</span><span class="preview-value">{{ entityClassificationData.psl.pslCategory }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">PSL Category</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.psl.pslCategory }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.psl.pslSubCategory) {
|
@if (entityClassificationData.psl.pslSubCategory) {
|
||||||
<div class="preview-field"><span class="preview-label">PSL Sub-category</span><span class="preview-value">{{ entityClassificationData.psl.pslSubCategory }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">PSL Sub-category</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.psl.pslSubCategory }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.psl.pslSanctionedLimit) {
|
@if (entityClassificationData.psl.pslSanctionedLimit) {
|
||||||
<div class="preview-field"><span class="preview-label">Sanctioned Limit</span><span class="preview-value">₹ {{ entityClassificationData.psl.pslSanctionedLimit | number }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Sanctioned Limit</span
|
||||||
|
><span class="preview-value">₹ {{ entityClassificationData.psl.pslSanctionedLimit | number }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.psl.fiddReportingCode) {
|
@if (entityClassificationData.psl.fiddReportingCode) {
|
||||||
<div class="preview-field"><span class="preview-label">FIDD Reporting Code</span><span class="preview-value mono">{{ entityClassificationData.psl.fiddReportingCode }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">FIDD Reporting Code</span
|
||||||
|
><span class="preview-value mono">{{ entityClassificationData.psl.fiddReportingCode }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.psl.weakerSectionFlag) {
|
@if (entityClassificationData.psl.weakerSectionFlag) {
|
||||||
<div class="preview-field"><span class="preview-label">Weaker Section</span><span class="preview-value"><span class="preview-badge preview-badge--verified">Yes</span></span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Weaker Section</span
|
||||||
|
><span class="preview-value"><span class="preview-badge preview-badge--verified">Yes</span></span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.psl.womenEntrepreneurFlag) {
|
@if (entityClassificationData.psl.womenEntrepreneurFlag) {
|
||||||
<div class="preview-field"><span class="preview-label">Women Entrepreneur</span><span class="preview-value"><span class="preview-badge preview-badge--verified">Yes</span></span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Women Entrepreneur</span
|
||||||
|
><span class="preview-value"><span class="preview-badge preview-badge--verified">Yes</span></span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -767,25 +977,46 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="preview-grid">
|
<div class="preview-grid">
|
||||||
@if (entityClassificationData.nps.industrySector) {
|
@if (entityClassificationData.nps.industrySector) {
|
||||||
<div class="preview-field"><span class="preview-label">Industry Sector</span><span class="preview-value">{{ entityClassificationData.nps.industrySector }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Industry Sector</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.nps.industrySector }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.nps.nicCode) {
|
@if (entityClassificationData.nps.nicCode) {
|
||||||
<div class="preview-field"><span class="preview-label">NIC Code</span><span class="preview-value mono">{{ entityClassificationData.nps.nicCode }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">NIC Code</span
|
||||||
|
><span class="preview-value mono">{{ entityClassificationData.nps.nicCode }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.nps.annualRevenueBand) {
|
@if (entityClassificationData.nps.annualRevenueBand) {
|
||||||
<div class="preview-field"><span class="preview-label">Annual Revenue Band</span><span class="preview-value">{{ entityClassificationData.nps.annualRevenueBand }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Annual Revenue Band</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.nps.annualRevenueBand }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.nps.riskCategory) {
|
@if (entityClassificationData.nps.riskCategory) {
|
||||||
<div class="preview-field"><span class="preview-label">Risk Category</span><span class="preview-value">{{ entityClassificationData.nps.riskCategory }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">Risk Category</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.nps.riskCategory }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.nps.amlRiskClassification) {
|
@if (entityClassificationData.nps.amlRiskClassification) {
|
||||||
<div class="preview-field"><span class="preview-label">AML Risk</span><span class="preview-value">{{ entityClassificationData.nps.amlRiskClassification }}</span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">AML Risk</span
|
||||||
|
><span class="preview-value">{{ entityClassificationData.nps.amlRiskClassification }}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.nps.pepFlag) {
|
@if (entityClassificationData.nps.pepFlag) {
|
||||||
<div class="preview-field"><span class="preview-label">PEP Flag</span><span class="preview-value"><span class="preview-badge preview-badge--danger">PEP</span></span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">PEP Flag</span
|
||||||
|
><span class="preview-value"><span class="preview-badge preview-badge--danger">PEP</span></span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (entityClassificationData.nps.amlWatchlistMatch) {
|
@if (entityClassificationData.nps.amlWatchlistMatch) {
|
||||||
<div class="preview-field"><span class="preview-label">AML Watchlist</span><span class="preview-value"><span class="preview-badge preview-badge--danger">Match Found</span></span></div>
|
<div class="preview-field">
|
||||||
|
<span class="preview-label">AML Watchlist</span
|
||||||
|
><span class="preview-value"><span class="preview-badge preview-badge--danger">Match Found</span></span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -793,58 +1024,64 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
<!-- Family Members (Individual only) -->
|
<!-- Family Members (Individual only) -->
|
||||||
@if (client?.legalFormId !== 2) {
|
@if (client?.legalFormId !== 2) {
|
||||||
<div class="info-card">
|
<div class="info-card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<fa-icon icon="users" class="card-icon"></fa-icon>
|
<fa-icon icon="users" class="card-icon"></fa-icon>
|
||||||
<span>Family Members</span>
|
<span>Family Members</span>
|
||||||
@if (familyMembers.length > 0) {
|
@if (familyMembers.length > 0) {
|
||||||
<span class="count-badge">{{ familyMembers.length }}</span>
|
<span class="count-badge">{{ familyMembers.length }}</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@if (familyMembers.length === 0) {
|
@if (familyMembers.length === 0) {
|
||||||
<div class="preview-empty preview-empty--warn">
|
<div class="preview-empty preview-empty--warn">
|
||||||
<mat-icon class="preview-empty__icon">warning</mat-icon>
|
<mat-icon class="preview-empty__icon">warning</mat-icon>
|
||||||
<span>No family members added. At least one is required.</span>
|
<span>No family members added. At least one is required.</span>
|
||||||
</div>
|
</div>
|
||||||
} @else {
|
} @else {
|
||||||
<div class="fm-preview-list">
|
<div class="fm-preview-list">
|
||||||
@for (member of familyMembers; track member; let i = $index) {
|
@for (member of familyMembers; track member; let i = $index) {
|
||||||
<div class="fm-preview-row">
|
<div class="fm-preview-row">
|
||||||
<div class="fm-preview-row__sno">{{ i + 1 }}</div>
|
<div class="fm-preview-row__sno">{{ i + 1 }}</div>
|
||||||
<div class="fm-preview-row__avatar">
|
<div class="fm-preview-row__avatar">
|
||||||
<mat-icon>person</mat-icon>
|
<mat-icon>person</mat-icon>
|
||||||
</div>
|
|
||||||
<div class="fm-preview-row__info">
|
|
||||||
<span class="fm-preview-row__name">{{ member.firstName || member.displayName }}</span>
|
|
||||||
<span class="fm-preview-row__meta">
|
|
||||||
@if (member.relationship) { {{ member.relationship }} }
|
|
||||||
@if (member.dateOfBirth) { · DOB: {{ member.dateOfBirth }} }
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
@if (member.aadhaarNumber || member.panNumber) {
|
|
||||||
<div class="fm-preview-row__ids">
|
|
||||||
@if (member.panNumber) { <span class="fm-preview-id">PAN: {{ member.panNumber }}</span> }
|
|
||||||
@if (member.aadhaarNumber) { <span class="fm-preview-id">Aadhaar: {{ member.aadhaarNumber }}</span> }
|
|
||||||
</div>
|
</div>
|
||||||
}
|
<div class="fm-preview-row__info">
|
||||||
<div class="fm-preview-row__status">
|
<span class="fm-preview-row__name">{{ member.firstName || member.displayName }}</span>
|
||||||
@if (member.isDependent) {
|
<span class="fm-preview-row__meta">
|
||||||
<span class="preview-badge preview-badge--info">Dependent</span>
|
@if (member.relationship) {
|
||||||
}
|
{{ member.relationship }}
|
||||||
@if (member.linkedClientId) {
|
}
|
||||||
<span class="preview-badge preview-badge--verified">Linked</span>
|
@if (member.dateOfBirth) {
|
||||||
|
· DOB: {{ member.dateOfBirth }}
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
@if (member.aadhaarNumber || member.panNumber) {
|
||||||
|
<div class="fm-preview-row__ids">
|
||||||
|
@if (member.panNumber) {
|
||||||
|
<span class="fm-preview-id">PAN: {{ member.panNumber }}</span>
|
||||||
|
}
|
||||||
|
@if (member.aadhaarNumber) {
|
||||||
|
<span class="fm-preview-id">Aadhaar: {{ member.aadhaarNumber }}</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
<div class="fm-preview-row__status">
|
||||||
|
@if (member.isDependent) {
|
||||||
|
<span class="preview-badge preview-badge--info">Dependent</span>
|
||||||
|
}
|
||||||
|
@if (member.linkedClientId) {
|
||||||
|
<span class="preview-badge preview-badge--verified">Linked</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
}
|
</div>
|
||||||
</div>
|
}
|
||||||
}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+14
-1
@@ -73,9 +73,22 @@ export class ClientPreviewStepComponent {
|
|||||||
@Input() maritalStatusId: number | null = null;
|
@Input() maritalStatusId: number | null = null;
|
||||||
/** Marital Status Options */
|
/** Marital Status Options */
|
||||||
@Input() maritalStatusOptions: any[] = [];
|
@Input() maritalStatusOptions: any[] = [];
|
||||||
|
/** Education Level Options */
|
||||||
|
@Input() educationLevelOptions: any[] = [];
|
||||||
|
/** Degree / Qualification Options */
|
||||||
|
@Input() degreeQualificationOptions: any[] = [];
|
||||||
|
/** Religion Options */
|
||||||
|
@Input() religionOptions: any[] = [];
|
||||||
|
/** Social Category Options */
|
||||||
|
@Input() socialCategoryOptions: any[] = [];
|
||||||
|
|
||||||
/** Address tab labels */
|
/** Address tab labels */
|
||||||
addressTabs = ['permanent', 'current', 'office', 'correspondence'];
|
addressTabs = [
|
||||||
|
'permanent',
|
||||||
|
'current',
|
||||||
|
'office',
|
||||||
|
'correspondence'
|
||||||
|
];
|
||||||
addressTabLabels: Record<string, string> = {
|
addressTabLabels: Record<string, string> = {
|
||||||
permanent: 'Permanent Address',
|
permanent: 'Permanent Address',
|
||||||
current: 'Current / Residential',
|
current: 'Current / Residential',
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<div class="personal-data-container mat-typography">
|
<div class="personal-data-container mat-typography">
|
||||||
|
|
||||||
<!-- Personal Information -->
|
<!-- Personal Information -->
|
||||||
<div class="pd-section">
|
<div class="pd-section">
|
||||||
<div class="pd-section__header">
|
<div class="pd-section__header">
|
||||||
@@ -50,13 +49,15 @@
|
|||||||
@if (clientViewData.dateOfBirth) {
|
@if (clientViewData.dateOfBirth) {
|
||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">{{ 'labels.inputs.Date of Birth' | translate }}</div>
|
<div class="pd-field__label">{{ 'labels.inputs.Date of Birth' | translate }}</div>
|
||||||
<div class="pd-field__value">{{ clientViewData.dateOfBirth | dateFormat:'DD-MMMM-YYYY' }}</div>
|
<div class="pd-field__value">{{ clientViewData.dateOfBirth | dateFormat: 'DD-MMMM-YYYY' }}</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (clientViewData.ageYears != null) {
|
@if (clientViewData.ageYears != null) {
|
||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">Age</div>
|
<div class="pd-field__label">Age</div>
|
||||||
<div class="pd-field__value">{{ clientViewData.ageYears }}y {{ clientViewData.ageMonths || 0 }}m {{ clientViewData.ageDays || 0 }}d</div>
|
<div class="pd-field__value">
|
||||||
|
{{ clientViewData.ageYears }}y {{ clientViewData.ageMonths || 0 }}m {{ clientViewData.ageDays || 0 }}d
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (clientViewData.gender) {
|
@if (clientViewData.gender) {
|
||||||
@@ -71,11 +72,39 @@
|
|||||||
<div class="pd-field__value">{{ clientViewData.maritalStatus.name }}</div>
|
<div class="pd-field__value">{{ clientViewData.maritalStatus.name }}</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@if (clientViewData.educationLevel) {
|
||||||
|
<div class="pd-field">
|
||||||
|
<div class="pd-field__label">Education Level</div>
|
||||||
|
<div class="pd-field__value">{{ clientViewData.educationLevel.name }}</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (clientViewData.degreeQualification) {
|
||||||
|
<div class="pd-field">
|
||||||
|
<div class="pd-field__label">Degree / Qualification</div>
|
||||||
|
<div class="pd-field__value">{{ clientViewData.degreeQualification.name }}</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (clientViewData.religion) {
|
||||||
|
<div class="pd-field">
|
||||||
|
<div class="pd-field__label">Religion</div>
|
||||||
|
<div class="pd-field__value">{{ clientViewData.religion.name }}</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (clientViewData.socialCategory) {
|
||||||
|
<div class="pd-field">
|
||||||
|
<div class="pd-field__label">Social Category</div>
|
||||||
|
<div class="pd-field__value">{{ clientViewData.socialCategory.name }}</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
@if (clientViewData.isMinor != null) {
|
@if (clientViewData.isMinor != null) {
|
||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">Minor</div>
|
<div class="pd-field__label">Minor</div>
|
||||||
<div class="pd-field__value">
|
<div class="pd-field__value">
|
||||||
<span class="pd-verify-badge" [class.pd-verify-badge--verified]="!clientViewData.isMinor" [class.pd-verify-badge--pending]="clientViewData.isMinor">
|
<span
|
||||||
|
class="pd-verify-badge"
|
||||||
|
[class.pd-verify-badge--verified]="!clientViewData.isMinor"
|
||||||
|
[class.pd-verify-badge--pending]="clientViewData.isMinor"
|
||||||
|
>
|
||||||
{{ clientViewData.isMinor ? 'Yes (Age < 10)' : 'No' }}
|
{{ clientViewData.isMinor ? 'Yes (Age < 10)' : 'No' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -84,7 +113,11 @@
|
|||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">{{ 'labels.inputs.Is staff' | translate }}</div>
|
<div class="pd-field__label">{{ 'labels.inputs.Is staff' | translate }}</div>
|
||||||
<div class="pd-field__value">
|
<div class="pd-field__value">
|
||||||
<span class="pd-verify-badge" [class.pd-verify-badge--verified]="clientViewData.isStaff" [class.pd-verify-badge--pending]="!clientViewData.isStaff">
|
<span
|
||||||
|
class="pd-verify-badge"
|
||||||
|
[class.pd-verify-badge--verified]="clientViewData.isStaff"
|
||||||
|
[class.pd-verify-badge--pending]="!clientViewData.isStaff"
|
||||||
|
>
|
||||||
{{ clientViewData.isStaff ? 'Yes' : 'No' }}
|
{{ clientViewData.isStaff ? 'Yes' : 'No' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -100,7 +133,7 @@
|
|||||||
@if (clientViewData.dateOfBirth) {
|
@if (clientViewData.dateOfBirth) {
|
||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">{{ 'labels.inputs.Incorporation Date' | translate }}</div>
|
<div class="pd-field__label">{{ 'labels.inputs.Incorporation Date' | translate }}</div>
|
||||||
<div class="pd-field__value">{{ clientViewData.dateOfBirth | dateFormat:'DD-MM-YYYY' }}</div>
|
<div class="pd-field__value">{{ clientViewData.dateOfBirth | dateFormat: 'DD-MM-YYYY' }}</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,7 +145,9 @@
|
|||||||
}
|
}
|
||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">Nationality</div>
|
<div class="pd-field__label">Nationality</div>
|
||||||
<div class="pd-field__value">{{ clientViewData.nationalityId || clientViewData.nationality || 'Indian' }}</div>
|
<div class="pd-field__value">
|
||||||
|
{{ clientViewData.nationalityId || clientViewData.nationality || 'Indian' }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -176,7 +211,9 @@
|
|||||||
@if (clientViewData.clientNonPersonDetails.incorpValidityTillDate) {
|
@if (clientViewData.clientNonPersonDetails.incorpValidityTillDate) {
|
||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">{{ 'labels.inputs.Incorporation Validity Till Date' | translate }}</div>
|
<div class="pd-field__label">{{ 'labels.inputs.Incorporation Validity Till Date' | translate }}</div>
|
||||||
<div class="pd-field__value">{{ clientViewData.clientNonPersonDetails.incorpValidityTillDate | dateFormat:'DD-MM-YYYY' }}</div>
|
<div class="pd-field__value">
|
||||||
|
{{ clientViewData.clientNonPersonDetails.incorpValidityTillDate | dateFormat: 'DD-MM-YYYY' }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (clientViewData.clientNonPersonDetails.incorpNumber) {
|
@if (clientViewData.clientNonPersonDetails.incorpNumber) {
|
||||||
@@ -221,7 +258,9 @@
|
|||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">{{ 'labels.inputs.Email' | translate }}</div>
|
<div class="pd-field__label">{{ 'labels.inputs.Email' | translate }}</div>
|
||||||
<div class="pd-field__value">
|
<div class="pd-field__value">
|
||||||
<span class="pd-contact-icon"><i class="fa fa-envelope-o"></i> {{ clientViewData.emailAddress || '-' }}</span>
|
<span class="pd-contact-icon"
|
||||||
|
><i class="fa fa-envelope-o"></i> {{ clientViewData.emailAddress || '-' }}</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -240,15 +279,19 @@
|
|||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">Mobile DIP Status</div>
|
<div class="pd-field__label">Mobile DIP Status</div>
|
||||||
<div class="pd-field__value">
|
<div class="pd-field__value">
|
||||||
@if (clientViewData.mobileVerified === true || clientViewData.mobileVerified === 'true' || clientViewData.mobileVerified === 1
|
@if (
|
||||||
|| clientViewData.dipVerified === true || clientViewData.dipVerified === 'true' || clientViewData.dipVerified === 1) {
|
clientViewData.mobileVerified === true ||
|
||||||
|
clientViewData.mobileVerified === 'true' ||
|
||||||
|
clientViewData.mobileVerified === 1 ||
|
||||||
|
clientViewData.dipVerified === true ||
|
||||||
|
clientViewData.dipVerified === 'true' ||
|
||||||
|
clientViewData.dipVerified === 1
|
||||||
|
) {
|
||||||
<span class="pd-verify-badge pd-verify-badge--verified">
|
<span class="pd-verify-badge pd-verify-badge--verified">
|
||||||
<i class="fa fa-check-circle"></i> Verified
|
<i class="fa fa-check-circle"></i> Verified
|
||||||
</span>
|
</span>
|
||||||
} @else {
|
} @else {
|
||||||
<span class="pd-verify-badge pd-verify-badge--pending">
|
<span class="pd-verify-badge pd-verify-badge--pending"> <i class="fa fa-clock-o"></i> Pending </span>
|
||||||
<i class="fa fa-clock-o"></i> Pending
|
|
||||||
</span>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -258,26 +301,21 @@
|
|||||||
<div class="pd-field__value monospace">{{ formatDateTime(clientViewData.dipTimestamp) }}</div>
|
<div class="pd-field__value monospace">{{ formatDateTime(clientViewData.dipTimestamp) }}</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (clientViewData.dipLookupLogId) {
|
|
||||||
<div class="pd-field">
|
|
||||||
<div class="pd-field__label">DIP Lookup Log ID</div>
|
|
||||||
<div class="pd-field__value monospace">{{ clientViewData.dipLookupLogId }}</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
<!-- Alternate Mobile DIP -->
|
<!-- Alternate Mobile DIP -->
|
||||||
@if (clientViewData.alternateMobileNo) {
|
@if (clientViewData.alternateMobileNo) {
|
||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">Alternate Mobile DIP Status</div>
|
<div class="pd-field__label">Alternate Mobile DIP Status</div>
|
||||||
<div class="pd-field__value">
|
<div class="pd-field__value">
|
||||||
@if (clientViewData.alternateDipVerified === true || clientViewData.alternateDipVerified === 'true' || clientViewData.alternateDipVerified === 1) {
|
@if (
|
||||||
|
clientViewData.alternateDipVerified === true ||
|
||||||
|
clientViewData.alternateDipVerified === 'true' ||
|
||||||
|
clientViewData.alternateDipVerified === 1
|
||||||
|
) {
|
||||||
<span class="pd-verify-badge pd-verify-badge--verified">
|
<span class="pd-verify-badge pd-verify-badge--verified">
|
||||||
<i class="fa fa-check-circle"></i> Verified
|
<i class="fa fa-check-circle"></i> Verified
|
||||||
</span>
|
</span>
|
||||||
} @else {
|
} @else {
|
||||||
<span class="pd-verify-badge pd-verify-badge--pending">
|
<span class="pd-verify-badge pd-verify-badge--pending"> <i class="fa fa-clock-o"></i> Pending </span>
|
||||||
<i class="fa fa-clock-o"></i> Pending
|
|
||||||
</span>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -287,93 +325,91 @@
|
|||||||
<div class="pd-field__value monospace">{{ formatDateTime(clientViewData.alternateDipTimestamp) }}</div>
|
<div class="pd-field__value monospace">{{ formatDateTime(clientViewData.alternateDipTimestamp) }}</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (clientViewData.alternateDipLookupLogId) {
|
|
||||||
<div class="pd-field">
|
|
||||||
<div class="pd-field__label">Alternate DIP Log ID</div>
|
|
||||||
<div class="pd-field__value monospace">{{ clientViewData.alternateDipLookupLogId }}</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- Sanctions / Name Screening -->
|
<!-- Sanctions / Name Screening -->
|
||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">Name Screening (Sanctions)</div>
|
<div class="pd-field__label">Name Screening (Sanctions)</div>
|
||||||
<div class="pd-field__value">
|
<div class="pd-field__value">
|
||||||
@if (clientViewData.nameVerified === true || clientViewData.nameVerified === 'true' || clientViewData.nameVerified === 1) {
|
@if (
|
||||||
|
clientViewData.nameVerified === true ||
|
||||||
|
clientViewData.nameVerified === 'true' ||
|
||||||
|
clientViewData.nameVerified === 1
|
||||||
|
) {
|
||||||
<span class="pd-verify-badge pd-verify-badge--verified"><i class="fa fa-check-circle"></i> Clear</span>
|
<span class="pd-verify-badge pd-verify-badge--verified"><i class="fa fa-check-circle"></i> Clear</span>
|
||||||
} @else if (clientViewData.nameVerified === false || clientViewData.nameVerified === 'false' || clientViewData.nameVerified === 0) {
|
} @else if (
|
||||||
<span class="pd-verify-badge pd-verify-badge--danger"><i class="fa fa-exclamation-triangle"></i> Match Found</span>
|
clientViewData.nameVerified === false ||
|
||||||
|
clientViewData.nameVerified === 'false' ||
|
||||||
|
clientViewData.nameVerified === 0
|
||||||
|
) {
|
||||||
|
<span class="pd-verify-badge pd-verify-badge--danger"
|
||||||
|
><i class="fa fa-exclamation-triangle"></i> Match Found</span
|
||||||
|
>
|
||||||
} @else {
|
} @else {
|
||||||
<span class="pd-verify-badge pd-verify-badge--pending"><i class="fa fa-clock-o"></i> Pending</span>
|
<span class="pd-verify-badge pd-verify-badge--pending"><i class="fa fa-clock-o"></i> Pending</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if (clientViewData.screeningLogId) {
|
|
||||||
<div class="pd-field">
|
|
||||||
<div class="pd-field__label">Screening Log ID</div>
|
|
||||||
<div class="pd-field__value monospace">{{ clientViewData.screeningLogId }}</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Financial & Classification (Individual only) -->
|
<!-- Financial & Classification (Individual only) -->
|
||||||
@if (clientViewData?.legalForm?.id !== 2) {
|
@if (clientViewData?.legalForm?.id !== 2) {
|
||||||
<div class="pd-section">
|
<div class="pd-section">
|
||||||
<div class="pd-section__header">
|
<div class="pd-section__header">
|
||||||
<i class="fa fa-chart-line"></i>
|
<i class="fa fa-chart-line"></i>
|
||||||
<h3>Financial & Classification</h3>
|
<h3>Financial & Classification</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="pd-section__body">
|
<div class="pd-section__body">
|
||||||
<div class="pd-grid">
|
<div class="pd-grid">
|
||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">Monthly Income</div>
|
<div class="pd-field__label">Monthly Income</div>
|
||||||
<div class="pd-field__value">
|
<div class="pd-field__value">
|
||||||
@if (clientViewData.monthlyIncome != null && clientViewData.monthlyIncome !== '') {
|
@if (clientViewData.monthlyIncome != null && clientViewData.monthlyIncome !== '') {
|
||||||
<span class="monospace">₹ {{ clientViewData.monthlyIncome | number }}</span>
|
<span class="monospace">₹ {{ clientViewData.monthlyIncome | number }}</span>
|
||||||
} @else {
|
} @else {
|
||||||
-
|
-
|
||||||
}
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="pd-field">
|
||||||
|
<div class="pd-field__label">Annual Turnover (Last FY)</div>
|
||||||
|
<div class="pd-field__value">
|
||||||
|
@if (clientViewData.annualTurnover != null && clientViewData.annualTurnover !== '') {
|
||||||
|
<span class="monospace">₹ {{ clientViewData.annualTurnover | number }}</span>
|
||||||
|
} @else {
|
||||||
|
-
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if (clientViewData.clientType) {
|
||||||
|
<div class="pd-field">
|
||||||
|
<div class="pd-field__label">{{ 'labels.inputs.Client Type' | translate }}</div>
|
||||||
|
<div class="pd-field__value">{{ clientViewData.clientType.name }}</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (clientViewData.clientClassification) {
|
||||||
|
<div class="pd-field">
|
||||||
|
<div class="pd-field__label">{{ 'labels.inputs.Client Classification' | translate }}</div>
|
||||||
|
<div class="pd-field__value">{{ clientViewData.clientClassification.name }}</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (clientViewData.occupationCategory) {
|
||||||
|
<div class="pd-field">
|
||||||
|
<div class="pd-field__label">{{ 'labels.inputs.Occupation Category' | translate }}</div>
|
||||||
|
<div class="pd-field__value">{{ clientViewData.occupationCategory.name }}</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (clientViewData.occupation) {
|
||||||
|
<div class="pd-field">
|
||||||
|
<div class="pd-field__label">{{ 'labels.inputs.Occupation' | translate }}</div>
|
||||||
|
<div class="pd-field__value">{{ clientViewData.occupation.name }}</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="pd-field">
|
|
||||||
<div class="pd-field__label">Annual Turnover (Last FY)</div>
|
|
||||||
<div class="pd-field__value">
|
|
||||||
@if (clientViewData.annualTurnover != null && clientViewData.annualTurnover !== '') {
|
|
||||||
<span class="monospace">₹ {{ clientViewData.annualTurnover | number }}</span>
|
|
||||||
} @else {
|
|
||||||
-
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@if (clientViewData.clientType) {
|
|
||||||
<div class="pd-field">
|
|
||||||
<div class="pd-field__label">{{ 'labels.inputs.Client Type' | translate }}</div>
|
|
||||||
<div class="pd-field__value">{{ clientViewData.clientType.name }}</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
@if (clientViewData.clientClassification) {
|
|
||||||
<div class="pd-field">
|
|
||||||
<div class="pd-field__label">{{ 'labels.inputs.Client Classification' | translate }}</div>
|
|
||||||
<div class="pd-field__value">{{ clientViewData.clientClassification.name }}</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
@if (clientViewData.occupationCategory) {
|
|
||||||
<div class="pd-field">
|
|
||||||
<div class="pd-field__label">{{ 'labels.inputs.Occupation Category' | translate }}</div>
|
|
||||||
<div class="pd-field__value">{{ clientViewData.occupationCategory.name }}</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
@if (clientViewData.occupation) {
|
|
||||||
<div class="pd-field">
|
|
||||||
<div class="pd-field__label">{{ 'labels.inputs.Occupation' | translate }}</div>
|
|
||||||
<div class="pd-field__value">{{ clientViewData.occupation.name }}</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- Guardian Details (Minor) -->
|
<!-- Guardian Details (Minor) -->
|
||||||
@@ -436,19 +472,19 @@
|
|||||||
@if (clientViewData.timeline?.submittedOnDate) {
|
@if (clientViewData.timeline?.submittedOnDate) {
|
||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">{{ 'labels.inputs.Submitted On' | translate }}</div>
|
<div class="pd-field__label">{{ 'labels.inputs.Submitted On' | translate }}</div>
|
||||||
<div class="pd-field__value">{{ clientViewData.timeline.submittedOnDate | dateFormat:'DD-MM-YYYY' }}</div>
|
<div class="pd-field__value">{{ clientViewData.timeline.submittedOnDate | dateFormat: 'DD-MM-YYYY' }}</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (clientViewData.activationDate) {
|
@if (clientViewData.activationDate) {
|
||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">{{ 'labels.inputs.Activation Date' | translate }}</div>
|
<div class="pd-field__label">{{ 'labels.inputs.Activation Date' | translate }}</div>
|
||||||
<div class="pd-field__value">{{ clientViewData.activationDate | dateFormat:'DD-MM-YYYY' }}</div>
|
<div class="pd-field__value">{{ clientViewData.activationDate | dateFormat: 'DD-MM-YYYY' }}</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (clientViewData.timeline?.closedOnDate) {
|
@if (clientViewData.timeline?.closedOnDate) {
|
||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">{{ 'labels.inputs.Closed Date' | translate }}</div>
|
<div class="pd-field__label">{{ 'labels.inputs.Closed Date' | translate }}</div>
|
||||||
<div class="pd-field__value">{{ clientViewData.timeline.closedOnDate | dateFormat:'DD-MM-YYYY' }}</div>
|
<div class="pd-field__value">{{ clientViewData.timeline.closedOnDate | dateFormat: 'DD-MM-YYYY' }}</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -467,10 +503,14 @@
|
|||||||
<div class="pd-field">
|
<div class="pd-field">
|
||||||
<div class="pd-field__label">{{ 'labels.inputs.Client Status' | translate }}</div>
|
<div class="pd-field__label">{{ 'labels.inputs.Client Status' | translate }}</div>
|
||||||
<div class="pd-field__value">
|
<div class="pd-field__value">
|
||||||
<span class="pd-field__value status-badge"
|
<span
|
||||||
|
class="pd-field__value status-badge"
|
||||||
[class.status-active]="clientViewData.status.value === 'Active'"
|
[class.status-active]="clientViewData.status.value === 'Active'"
|
||||||
[class.status-closed]="clientViewData.status.value === 'Closed'"
|
[class.status-closed]="clientViewData.status.value === 'Closed'"
|
||||||
[class.status-pending]="clientViewData.status.value !== 'Active' && clientViewData.status.value !== 'Closed'">
|
[class.status-pending]="
|
||||||
|
clientViewData.status.value !== 'Active' && clientViewData.status.value !== 'Closed'
|
||||||
|
"
|
||||||
|
>
|
||||||
{{ 'labels.status.' + clientViewData.status.value | translate }}
|
{{ 'labels.status.' + clientViewData.status.value | translate }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -485,5 +525,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -74,7 +74,6 @@
|
|||||||
<mat-option value="pending">CKYC Pending</mat-option>
|
<mat-option value="pending">CKYC Pending</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -89,7 +88,9 @@
|
|||||||
<ng-container matColumnDef="displayName">
|
<ng-container matColumnDef="displayName">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.name' | translate }}</th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.name' | translate }}</th>
|
||||||
<td mat-cell *matCellDef="let row" class="cell-link">
|
<td mat-cell *matCellDef="let row" class="cell-link">
|
||||||
<mat-icon class="row-legal-icon" [ngClass]="row.legalForm?.id === 2 ? 'entity' : 'person'">{{ row.legalForm?.id === 2 ? 'business' : 'person' }}</mat-icon>
|
<mat-icon class="row-legal-icon" [ngClass]="row.legalForm?.id === 2 ? 'entity' : 'person'">{{
|
||||||
|
row.legalForm?.id === 2 ? 'business' : 'person'
|
||||||
|
}}</mat-icon>
|
||||||
{{ hideClientData ? maskName(row.displayName) : row.displayName }}
|
{{ hideClientData ? maskName(row.displayName) : row.displayName }}
|
||||||
@if (row._ckycDone) {
|
@if (row._ckycDone) {
|
||||||
<mat-icon class="row-ckyc-icon" matTooltip="CKYC Done">verified</mat-icon>
|
<mat-icon class="row-ckyc-icon" matTooltip="CKYC Done">verified</mat-icon>
|
||||||
@@ -111,18 +112,6 @@
|
|||||||
<td mat-cell *matCellDef="let row" class="cell-mono">{{ row.cifNumber }}</td>
|
<td mat-cell *matCellDef="let row" class="cell-mono">{{ row.cifNumber }}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- CKYC Number Column -->
|
|
||||||
<ng-container matColumnDef="ckycNumber">
|
|
||||||
<th mat-header-cell *matHeaderCellDef>CKYC Number</th>
|
|
||||||
<td mat-cell *matCellDef="let row" class="cell-mono">
|
|
||||||
@if (row._ckycNumber) {
|
|
||||||
{{ row._ckycNumber }}
|
|
||||||
} @else {
|
|
||||||
<span class="ckyc-pending">—</span>
|
|
||||||
}
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<!-- Legal Form Column -->
|
<!-- Legal Form Column -->
|
||||||
<ng-container matColumnDef="legalForm">
|
<ng-container matColumnDef="legalForm">
|
||||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Legal Form' | translate }}</th>
|
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Legal Form' | translate }}</th>
|
||||||
@@ -149,7 +138,11 @@
|
|||||||
<td mat-cell *matCellDef="let row">
|
<td mat-cell *matCellDef="let row">
|
||||||
<div class="profile-steps">
|
<div class="profile-steps">
|
||||||
@for (step of getProfileSteps(row); track step.label) {
|
@for (step of getProfileSteps(row); track step.label) {
|
||||||
<span class="step-dot" [class.done]="step.done" [matTooltip]="step.label + (step.done ? ' ✓' : ' — Pending')">
|
<span
|
||||||
|
class="step-dot"
|
||||||
|
[class.done]="step.done"
|
||||||
|
[matTooltip]="step.label + (step.done ? ' ✓' : ' — Pending')"
|
||||||
|
>
|
||||||
{{ step.label.charAt(0) }}
|
{{ step.label.charAt(0) }}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
@@ -157,12 +150,6 @@
|
|||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- Office Column -->
|
|
||||||
<ng-container matColumnDef="officeName">
|
|
||||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Office Name' | translate }}</th>
|
|
||||||
<td mat-cell *matCellDef="let row">{{ row.officeName }}</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<!-- Actions Column -->
|
<!-- Actions Column -->
|
||||||
<ng-container matColumnDef="actions">
|
<ng-container matColumnDef="actions">
|
||||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
|
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
|
||||||
|
|||||||
@@ -90,11 +90,9 @@ export class ClientsComponent implements OnInit {
|
|||||||
'displayName',
|
'displayName',
|
||||||
'accountNumber',
|
'accountNumber',
|
||||||
'cifNumber',
|
'cifNumber',
|
||||||
'ckycNumber',
|
|
||||||
'legalForm',
|
'legalForm',
|
||||||
'status',
|
'status',
|
||||||
'profileCompletion',
|
'profileCompletion',
|
||||||
'officeName',
|
|
||||||
'actions'
|
'actions'
|
||||||
];
|
];
|
||||||
dataSource: MatTableDataSource<any> = new MatTableDataSource();
|
dataSource: MatTableDataSource<any> = new MatTableDataSource();
|
||||||
@@ -167,34 +165,37 @@ export class ClientsComponent implements OnInit {
|
|||||||
|
|
||||||
// Use individual subscriptions instead of forkJoin to avoid EMPTY observable issues
|
// Use individual subscriptions instead of forkJoin to avoid EMPTY observable issues
|
||||||
clients.forEach((client, i) => {
|
clients.forEach((client, i) => {
|
||||||
this.clientService.getClientData(client.id?.toString()).pipe(
|
this.clientService
|
||||||
catchError(() => of(null))
|
.getClientData(client.id?.toString())
|
||||||
).subscribe((data: any) => {
|
.pipe(catchError(() => of(null)))
|
||||||
if (data?.legalForm) {
|
.subscribe((data: any) => {
|
||||||
clients[i].legalForm = data.legalForm;
|
if (data?.legalForm) {
|
||||||
this.applyClientFilters();
|
clients[i].legalForm = data.legalForm;
|
||||||
}
|
this.applyClientFilters();
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.clientService.getClientKyc(client.id?.toString()).pipe(
|
this.clientService
|
||||||
catchError(() => of(null))
|
.getClientKyc(client.id?.toString())
|
||||||
).subscribe((kyc: any) => {
|
.pipe(catchError(() => of(null)))
|
||||||
if (kyc) {
|
.subscribe((kyc: any) => {
|
||||||
clients[i]._kycDone = kyc.kycStatus === 300;
|
if (kyc) {
|
||||||
clients[i]._ckycDone = !!kyc.ckycNumber;
|
clients[i]._kycDone = kyc.kycStatus === 300;
|
||||||
clients[i]._ckycNumber = kyc.ckycNumber || '';
|
clients[i]._ckycDone = !!kyc.ckycNumber;
|
||||||
this.applyClientFilters();
|
clients[i]._ckycNumber = kyc.ckycNumber || '';
|
||||||
}
|
this.applyClientFilters();
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.clientService.getClientAddressData(client.id?.toString()).pipe(
|
this.clientService
|
||||||
catchError(() => of(null))
|
.getClientAddressData(client.id?.toString())
|
||||||
).subscribe((addr: any) => {
|
.pipe(catchError(() => of(null)))
|
||||||
if (addr && Array.isArray(addr) && addr.length > 0) {
|
.subscribe((addr: any) => {
|
||||||
clients[i]._addressDone = true;
|
if (addr && Array.isArray(addr) && addr.length > 0) {
|
||||||
this.applyClientFilters();
|
clients[i]._addressDone = true;
|
||||||
}
|
this.applyClientFilters();
|
||||||
});
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +256,7 @@ export class ClientsComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCompletedCount(row: any): number {
|
getCompletedCount(row: any): number {
|
||||||
return this.getProfileSteps(row).filter(s => s.done).length;
|
return this.getProfileSteps(row).filter((s) => s.done).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
private resetPaginator() {
|
private resetPaginator() {
|
||||||
|
|||||||
@@ -12,7 +12,12 @@
|
|||||||
<h2>{{ 'labels.heading.Create Client' | translate }}</h2>
|
<h2>{{ 'labels.heading.Create Client' | translate }}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<mat-tab-group class="client-tabs" animationDuration="200ms" [preserveContent]="true" [(selectedIndex)]="selectedTabIndex">
|
<mat-tab-group
|
||||||
|
class="client-tabs"
|
||||||
|
animationDuration="200ms"
|
||||||
|
[preserveContent]="true"
|
||||||
|
[(selectedIndex)]="selectedTabIndex"
|
||||||
|
>
|
||||||
<!-- Tab 1: General Details -->
|
<!-- Tab 1: General Details -->
|
||||||
<mat-tab>
|
<mat-tab>
|
||||||
<ng-template mat-tab-label>
|
<ng-template mat-tab-label>
|
||||||
@@ -62,7 +67,8 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<div class="tab-section">
|
<div class="tab-section">
|
||||||
<mifosx-client-kyc-step #clientKyc
|
<mifosx-client-kyc-step
|
||||||
|
#clientKyc
|
||||||
[isNonIndividual]="legalFormType === 2"
|
[isNonIndividual]="legalFormType === 2"
|
||||||
[clientId]="createdClientId"
|
[clientId]="createdClientId"
|
||||||
[constitutionMeta]="clientGeneralStep?.selectedConstitution"
|
[constitutionMeta]="clientGeneralStep?.selectedConstitution"
|
||||||
@@ -127,13 +133,18 @@
|
|||||||
<mat-icon>edit</mat-icon> Edit
|
<mat-icon>edit</mat-icon> Edit
|
||||||
</button>
|
</button>
|
||||||
} @else {
|
} @else {
|
||||||
<button mat-stroked-button class="tab-mode-btn tab-mode-btn--cancel" (click)="cancelTabEdit(addressTabIdx)">
|
<button
|
||||||
|
mat-stroked-button
|
||||||
|
class="tab-mode-btn tab-mode-btn--cancel"
|
||||||
|
(click)="cancelTabEdit(addressTabIdx)"
|
||||||
|
>
|
||||||
<mat-icon>close</mat-icon> Cancel
|
<mat-icon>close</mat-icon> Cancel
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<mifosx-client-india-address-step #clientIndiaAddress
|
<mifosx-client-india-address-step
|
||||||
|
#clientIndiaAddress
|
||||||
[readOnly]="isTabReadOnly(addressTabIdx)"
|
[readOnly]="isTabReadOnly(addressTabIdx)"
|
||||||
></mifosx-client-india-address-step>
|
></mifosx-client-india-address-step>
|
||||||
</div>
|
</div>
|
||||||
@@ -155,13 +166,18 @@
|
|||||||
<mat-icon>edit</mat-icon> Edit
|
<mat-icon>edit</mat-icon> Edit
|
||||||
</button>
|
</button>
|
||||||
} @else {
|
} @else {
|
||||||
<button mat-stroked-button class="tab-mode-btn tab-mode-btn--cancel" (click)="cancelTabEdit(familyTabIdx)">
|
<button
|
||||||
|
mat-stroked-button
|
||||||
|
class="tab-mode-btn tab-mode-btn--cancel"
|
||||||
|
(click)="cancelTabEdit(familyTabIdx)"
|
||||||
|
>
|
||||||
<mat-icon>close</mat-icon> Cancel
|
<mat-icon>close</mat-icon> Cancel
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<mifosx-client-family-members-step #clientFamilyMembers
|
<mifosx-client-family-members-step
|
||||||
|
#clientFamilyMembers
|
||||||
[clientTemplate]="clientTemplate"
|
[clientTemplate]="clientTemplate"
|
||||||
[clientId]="createdClientId"
|
[clientId]="createdClientId"
|
||||||
[maritalStatusId]="clientGeneralStep?.createClientForm?.get('maritalStatusId')?.value"
|
[maritalStatusId]="clientGeneralStep?.createClientForm?.get('maritalStatusId')?.value"
|
||||||
@@ -191,6 +207,10 @@
|
|||||||
[familyMembers]="clientFamilyMembersStep?.clientFamilyMembers || []"
|
[familyMembers]="clientFamilyMembersStep?.clientFamilyMembers || []"
|
||||||
[maritalStatusId]="clientGeneralStep?.createClientForm?.get('maritalStatusId')?.value"
|
[maritalStatusId]="clientGeneralStep?.createClientForm?.get('maritalStatusId')?.value"
|
||||||
[maritalStatusOptions]="clientGeneralStep?.maritalStatusOptions || []"
|
[maritalStatusOptions]="clientGeneralStep?.maritalStatusOptions || []"
|
||||||
|
[educationLevelOptions]="clientGeneralStep?.educationLevelOptions || []"
|
||||||
|
[degreeQualificationOptions]="clientGeneralStep?.degreeQualificationOptions || []"
|
||||||
|
[religionOptions]="clientGeneralStep?.religionOptions || []"
|
||||||
|
[socialCategoryOptions]="clientGeneralStep?.socialCategoryOptions || []"
|
||||||
(submitEvent)="submit()"
|
(submitEvent)="submit()"
|
||||||
></mifosx-client-preview-step>
|
></mifosx-client-preview-step>
|
||||||
</div>
|
</div>
|
||||||
@@ -220,9 +240,19 @@
|
|||||||
}
|
}
|
||||||
@if (selectedTabIndex < totalTabs - 1) {
|
@if (selectedTabIndex < totalTabs - 1) {
|
||||||
<div class="save-next-wrapper">
|
<div class="save-next-wrapper">
|
||||||
<button mat-raised-button color="primary" class="save-next-btn" (click)="onNext()" [disabled]="savingClient || (selectedTabIndex === 0 && clientGeneralStep?.sanctionsBlocked)">
|
<button
|
||||||
|
mat-raised-button
|
||||||
|
color="primary"
|
||||||
|
class="save-next-btn"
|
||||||
|
(click)="onNext()"
|
||||||
|
[disabled]="savingClient || (selectedTabIndex === 0 && clientGeneralStep?.sanctionsBlocked)"
|
||||||
|
>
|
||||||
@if (savingClient) {
|
@if (savingClient) {
|
||||||
<mat-progress-spinner diameter="18" mode="indeterminate" class="m-r-10 save-spinner"></mat-progress-spinner>
|
<mat-progress-spinner
|
||||||
|
diameter="18"
|
||||||
|
mode="indeterminate"
|
||||||
|
class="m-r-10 save-spinner"
|
||||||
|
></mat-progress-spinner>
|
||||||
Saving...
|
Saving...
|
||||||
} @else {
|
} @else {
|
||||||
<mat-icon class="m-r-6">save</mat-icon>
|
<mat-icon class="m-r-6">save</mat-icon>
|
||||||
|
|||||||
@@ -198,6 +198,26 @@ export class CreateClientComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanctions verification gate — Verify Client must be clicked before save
|
||||||
|
if (!this.clientGeneralStep?.sanctionsVerified) {
|
||||||
|
this.dialog
|
||||||
|
.open(VerifyClientAlertDialogComponent, {
|
||||||
|
width: '420px',
|
||||||
|
autoFocus: false
|
||||||
|
})
|
||||||
|
.afterClosed()
|
||||||
|
.subscribe(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
const verifyBtn = document.querySelector('.verify-name-btn') as HTMLElement;
|
||||||
|
if (verifyBtn) {
|
||||||
|
verifyBtn.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||||
|
verifyBtn.focus();
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Show confirmation dialog
|
// Show confirmation dialog
|
||||||
const dialogRef = this.dialog.open(SaveConfirmDialogComponent, {
|
const dialogRef = this.dialog.open(SaveConfirmDialogComponent, {
|
||||||
width: '440px',
|
width: '440px',
|
||||||
@@ -236,10 +256,14 @@ export class CreateClientComponent {
|
|||||||
}
|
}
|
||||||
// Upload photo & signature
|
// Upload photo & signature
|
||||||
if (this.clientKycStep?.photographFile) {
|
if (this.clientKycStep?.photographFile) {
|
||||||
this.clientsService.uploadClientProfileImage(clientId, this.clientKycStep.photographFile).subscribe({ error: () => {} });
|
this.clientsService
|
||||||
|
.uploadClientProfileImage(clientId, this.clientKycStep.photographFile)
|
||||||
|
.subscribe({ error: () => {} });
|
||||||
}
|
}
|
||||||
if (this.clientKycStep?.signatureFile) {
|
if (this.clientKycStep?.signatureFile) {
|
||||||
this.clientsService.uploadClientSignatureImage(clientId, this.clientKycStep.signatureFile).subscribe({ error: () => {} });
|
this.clientsService
|
||||||
|
.uploadClientSignatureImage(clientId, this.clientKycStep.signatureFile)
|
||||||
|
.subscribe({ error: () => {} });
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -368,16 +392,27 @@ export class CreateClientComponent {
|
|||||||
* Finalize: upload photo/signature, save KYC, save addresses, then navigate.
|
* Finalize: upload photo/signature, save KYC, save addresses, then navigate.
|
||||||
*/
|
*/
|
||||||
private finalizeClient(clientId: string) {
|
private finalizeClient(clientId: string) {
|
||||||
const navigateToClient = () => this.router.navigate(['../', clientId], { relativeTo: this.route });
|
const navigateToClient = () =>
|
||||||
|
this.router.navigate(
|
||||||
|
[
|
||||||
|
'../',
|
||||||
|
clientId
|
||||||
|
],
|
||||||
|
{ relativeTo: this.route }
|
||||||
|
);
|
||||||
|
|
||||||
// Upload photo if selected
|
// Upload photo if selected
|
||||||
if (this.clientKycStep?.photographFile) {
|
if (this.clientKycStep?.photographFile) {
|
||||||
this.clientsService.uploadClientProfileImage(clientId, this.clientKycStep.photographFile).subscribe({ error: () => {} });
|
this.clientsService
|
||||||
|
.uploadClientProfileImage(clientId, this.clientKycStep.photographFile)
|
||||||
|
.subscribe({ error: () => {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upload signature if selected
|
// Upload signature if selected
|
||||||
if (this.clientKycStep?.signatureFile) {
|
if (this.clientKycStep?.signatureFile) {
|
||||||
this.clientsService.uploadClientSignatureImage(clientId, this.clientKycStep.signatureFile).subscribe({ error: () => {} });
|
this.clientsService
|
||||||
|
.uploadClientSignatureImage(clientId, this.clientKycStep.signatureFile)
|
||||||
|
.subscribe({ error: () => {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save addresses from India address step
|
// Save addresses from India address step
|
||||||
@@ -409,16 +444,36 @@ export class CreateClientComponent {
|
|||||||
const addressData = this.clientIndiaAddressStep.addressData;
|
const addressData = this.clientIndiaAddressStep.addressData;
|
||||||
// Map tab names to Fineract address type names (as defined in address template)
|
// Map tab names to Fineract address type names (as defined in address template)
|
||||||
const typeNameMap: Record<string, string[]> = {
|
const typeNameMap: Record<string, string[]> = {
|
||||||
permanent: ['Permanent', 'Permanent Address'],
|
permanent: [
|
||||||
current: ['Residential', 'Current', 'Current / Residential', 'Communication'],
|
'Permanent',
|
||||||
office: ['Office', 'Office / Work', 'Business', 'Work'],
|
'Permanent Address'
|
||||||
correspondence: ['Correspondence', 'Mailing', 'Postal']
|
],
|
||||||
|
current: [
|
||||||
|
'Residential',
|
||||||
|
'Current',
|
||||||
|
'Current / Residential',
|
||||||
|
'Communication'
|
||||||
|
],
|
||||||
|
office: [
|
||||||
|
'Office',
|
||||||
|
'Office / Work',
|
||||||
|
'Business',
|
||||||
|
'Work'
|
||||||
|
],
|
||||||
|
correspondence: [
|
||||||
|
'Correspondence',
|
||||||
|
'Mailing',
|
||||||
|
'Postal'
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
this.clientsService.getClientAddressTemplate().subscribe({
|
this.clientsService.getClientAddressTemplate().subscribe({
|
||||||
next: (template: any) => {
|
next: (template: any) => {
|
||||||
const typeOptions = template?.addressTypeIdOptions || [];
|
const typeOptions = template?.addressTypeIdOptions || [];
|
||||||
for (const [tab, addr] of Object.entries(addressData)) {
|
for (const [
|
||||||
|
tab,
|
||||||
|
addr
|
||||||
|
] of Object.entries(addressData)) {
|
||||||
if (!addr || !(addr as any).addressLine1) continue;
|
if (!addr || !(addr as any).addressLine1) continue;
|
||||||
|
|
||||||
// Find matching address type ID
|
// Find matching address type ID
|
||||||
@@ -448,8 +503,8 @@ export class CreateClientComponent {
|
|||||||
|
|
||||||
// Try to resolve state to stateProvinceId
|
// Try to resolve state to stateProvinceId
|
||||||
if ((addr as any).state && template?.stateProvinceIdOptions?.length) {
|
if ((addr as any).state && template?.stateProvinceIdOptions?.length) {
|
||||||
const stateMatch = template.stateProvinceIdOptions.find((s: any) =>
|
const stateMatch = template.stateProvinceIdOptions.find(
|
||||||
s.name?.toLowerCase() === (addr as any).state?.toLowerCase()
|
(s: any) => s.name?.toLowerCase() === (addr as any).state?.toLowerCase()
|
||||||
);
|
);
|
||||||
if (stateMatch) payload.stateProvinceId = stateMatch.id;
|
if (stateMatch) payload.stateProvinceId = stateMatch.id;
|
||||||
}
|
}
|
||||||
@@ -535,34 +590,228 @@ export class CreateClientComponent {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
styles: [`
|
styles: [
|
||||||
.scd { background: #fff; border-radius: 12px; overflow: hidden; }
|
`
|
||||||
.scd-header {
|
.scd {
|
||||||
display: flex; align-items: center; gap: 14px;
|
background: #fff;
|
||||||
padding: 20px 24px 16px;
|
border-radius: 12px;
|
||||||
}
|
overflow: hidden;
|
||||||
.scd-header__icon-wrap {
|
}
|
||||||
width: 44px; height: 44px; border-radius: 12px;
|
.scd-header {
|
||||||
background: #eff6ff; display: flex; align-items: center; justify-content: center;
|
display: flex;
|
||||||
}
|
align-items: center;
|
||||||
.scd-header__icon { color: #1074b9; font-size: 24px; width: 24px; height: 24px; }
|
gap: 14px;
|
||||||
.scd-header__title { margin: 0; font-size: 17px; font-weight: 700; color: #0f172a; }
|
padding: 20px 24px 16px;
|
||||||
.scd-header__sub { margin: 2px 0 0; font-size: 12px; color: #64748b; }
|
}
|
||||||
.scd-body { padding: 0 24px 20px; }
|
.scd-header__icon-wrap {
|
||||||
.scd-body p { margin: 0 0 14px; font-size: 14px; color: #374151; line-height: 1.5; }
|
width: 44px;
|
||||||
.scd-info {
|
height: 44px;
|
||||||
display: flex; align-items: flex-start; gap: 8px;
|
border-radius: 12px;
|
||||||
padding: 10px 14px; background: #f0f9ff; border: 1px solid #bae6fd;
|
background: #eff6ff;
|
||||||
border-radius: 8px; font-size: 12px; color: #0c4a6e;
|
display: flex;
|
||||||
}
|
align-items: center;
|
||||||
.scd-info__icon { font-size: 16px !important; width: 16px !important; height: 16px !important; color: #0284c7; flex-shrink: 0; margin-top: 1px; }
|
justify-content: center;
|
||||||
.scd-actions {
|
}
|
||||||
display: flex; justify-content: flex-end; gap: 10px;
|
.scd-header__icon {
|
||||||
padding: 14px 24px; border-top: 1px solid #f1f5f9; background: #f8fafc;
|
color: #1074b9;
|
||||||
}
|
font-size: 24px;
|
||||||
.scd-cancel, .scd-confirm { display: flex !important; align-items: center; gap: 6px; font-size: 13px !important; height: 38px !important; border-radius: 8px !important; }
|
width: 24px;
|
||||||
.scd-confirm { font-weight: 600 !important; }
|
height: 24px;
|
||||||
`],
|
}
|
||||||
imports: [MatIcon, MatDialogClose]
|
.scd-header__title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #0f172a;
|
||||||
|
}
|
||||||
|
.scd-header__sub {
|
||||||
|
margin: 2px 0 0;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
.scd-body {
|
||||||
|
padding: 0 24px 20px;
|
||||||
|
}
|
||||||
|
.scd-body p {
|
||||||
|
margin: 0 0 14px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #374151;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
.scd-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 10px 14px;
|
||||||
|
background: #f0f9ff;
|
||||||
|
border: 1px solid #bae6fd;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #0c4a6e;
|
||||||
|
}
|
||||||
|
.scd-info__icon {
|
||||||
|
font-size: 16px !important;
|
||||||
|
width: 16px !important;
|
||||||
|
height: 16px !important;
|
||||||
|
color: #0284c7;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
.scd-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 14px 24px;
|
||||||
|
border-top: 1px solid #f1f5f9;
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
|
.scd-cancel,
|
||||||
|
.scd-confirm {
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
font-size: 13px !important;
|
||||||
|
height: 38px !important;
|
||||||
|
border-radius: 8px !important;
|
||||||
|
}
|
||||||
|
.scd-confirm {
|
||||||
|
font-weight: 600 !important;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
MatIcon,
|
||||||
|
MatDialogClose
|
||||||
|
]
|
||||||
})
|
})
|
||||||
export class SaveConfirmDialogComponent {}
|
export class SaveConfirmDialogComponent {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify Client Required Alert Dialog
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-verify-client-alert-dialog',
|
||||||
|
template: `
|
||||||
|
<div class="vcad">
|
||||||
|
<div class="vcad-header">
|
||||||
|
<div class="vcad-header__icon-wrap">
|
||||||
|
<mat-icon class="vcad-header__icon">shield</mat-icon>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="vcad-header__title">Verification Required</h3>
|
||||||
|
<p class="vcad-header__sub">Client name must be screened before saving</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="vcad-body">
|
||||||
|
<p>
|
||||||
|
Please click <strong>Verify Client</strong> to screen the client name against the UN Security Council
|
||||||
|
Consolidated Sanctions List before proceeding.
|
||||||
|
</p>
|
||||||
|
<div class="vcad-info">
|
||||||
|
<mat-icon class="vcad-info__icon">gavel</mat-icon>
|
||||||
|
<span
|
||||||
|
>RBI KYC Master Direction (2016) — Section 51 & PMLA 2002. Sanctions screening is mandatory before
|
||||||
|
account opening.</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="vcad-actions">
|
||||||
|
<button mat-flat-button color="primary" [mat-dialog-close]="true" class="vcad-ok">
|
||||||
|
<mat-icon>check</mat-icon>
|
||||||
|
OK, Verify Now
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
styles: [
|
||||||
|
`
|
||||||
|
.vcad {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.vcad-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 14px;
|
||||||
|
padding: 20px 24px 16px;
|
||||||
|
}
|
||||||
|
.vcad-header__icon-wrap {
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: #fef3c7;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.vcad-header__icon {
|
||||||
|
color: #d97706;
|
||||||
|
font-size: 24px;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
.vcad-header__title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #0f172a;
|
||||||
|
}
|
||||||
|
.vcad-header__sub {
|
||||||
|
margin: 2px 0 0;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
.vcad-body {
|
||||||
|
padding: 0 24px 20px;
|
||||||
|
}
|
||||||
|
.vcad-body p {
|
||||||
|
margin: 0 0 14px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #374151;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
.vcad-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 10px 14px;
|
||||||
|
background: #fff7ed;
|
||||||
|
border: 1px solid #fed7aa;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #7c2d12;
|
||||||
|
}
|
||||||
|
.vcad-info__icon {
|
||||||
|
font-size: 16px !important;
|
||||||
|
width: 16px !important;
|
||||||
|
height: 16px !important;
|
||||||
|
color: #d97706;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
.vcad-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 14px 24px;
|
||||||
|
border-top: 1px solid #f1f5f9;
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
|
.vcad-ok {
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
font-size: 13px !important;
|
||||||
|
height: 38px !important;
|
||||||
|
border-radius: 8px !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
MatIcon,
|
||||||
|
MatDialogClose
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class VerifyClientAlertDialogComponent {}
|
||||||
|
|||||||
@@ -180,6 +180,12 @@
|
|||||||
[addressData]="clientIndiaAddressStep?.addressData"
|
[addressData]="clientIndiaAddressStep?.addressData"
|
||||||
[guardian]="clientGeneralStep?.selectedGuardian"
|
[guardian]="clientGeneralStep?.selectedGuardian"
|
||||||
[guardianRelation]="clientGeneralStep?.createClientForm?.get('guardianDetails.guardianRelation')?.value || ''"
|
[guardianRelation]="clientGeneralStep?.createClientForm?.get('guardianDetails.guardianRelation')?.value || ''"
|
||||||
|
[maritalStatusId]="clientGeneralStep?.createClientForm?.get('maritalStatusId')?.value"
|
||||||
|
[maritalStatusOptions]="clientGeneralStep?.maritalStatusOptions || []"
|
||||||
|
[educationLevelOptions]="clientGeneralStep?.educationLevelOptions || []"
|
||||||
|
[degreeQualificationOptions]="clientGeneralStep?.degreeQualificationOptions || []"
|
||||||
|
[religionOptions]="clientGeneralStep?.religionOptions || []"
|
||||||
|
[socialCategoryOptions]="clientGeneralStep?.socialCategoryOptions || []"
|
||||||
(submitEvent)="submit()"
|
(submitEvent)="submit()"
|
||||||
></mifosx-client-preview-step>
|
></mifosx-client-preview-step>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -77,15 +77,24 @@
|
|||||||
|
|
||||||
<div class="km-filters">
|
<div class="km-filters">
|
||||||
<select class="km-fsel">
|
<select class="km-fsel">
|
||||||
<option>All Risk</option><option>Low</option><option>Mid</option><option>High</option>
|
<option>All Risk</option>
|
||||||
|
<option>Low</option>
|
||||||
|
<option>Mid</option>
|
||||||
|
<option>High</option>
|
||||||
</select>
|
</select>
|
||||||
<select class="km-fsel">
|
<select class="km-fsel">
|
||||||
<option>All States</option><option>Alert Window</option><option>Debit Freeze</option>
|
<option>All States</option>
|
||||||
<option>Inoperative</option><option>Dormant</option>
|
<option>Alert Window</option>
|
||||||
|
<option>Debit Freeze</option>
|
||||||
|
<option>Inoperative</option>
|
||||||
|
<option>Dormant</option>
|
||||||
</select>
|
</select>
|
||||||
<select class="km-fsel">
|
<select class="km-fsel">
|
||||||
<option>All Notices</option><option>Notice 1 Pending</option><option>Notice 2 Pending</option>
|
<option>All Notices</option>
|
||||||
<option>Notice 3 Pending</option><option>All 3 Sent</option>
|
<option>Notice 1 Pending</option>
|
||||||
|
<option>Notice 2 Pending</option>
|
||||||
|
<option>Notice 3 Pending</option>
|
||||||
|
<option>All 3 Sent</option>
|
||||||
</select>
|
</select>
|
||||||
<input class="km-finp" type="text" placeholder="Search name or account..." />
|
<input class="km-finp" type="text" placeholder="Search name or account..." />
|
||||||
<button class="km-btn km-btn-t" (click)="toast('Filters applied')">Apply</button>
|
<button class="km-btn km-btn-t" (click)="toast('Filters applied')">Apply</button>
|
||||||
@@ -100,8 +109,15 @@
|
|||||||
<table class="km-tbl">
|
<table class="km-tbl">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Customer</th><th>Risk</th><th>Expiry Date</th><th>Days Left</th>
|
<th>Customer</th>
|
||||||
<th>Notices</th><th>State</th><th>Pending Action</th><th>Next Stage</th><th></th>
|
<th>Risk</th>
|
||||||
|
<th>Expiry Date</th>
|
||||||
|
<th>Days Left</th>
|
||||||
|
<th>Notices</th>
|
||||||
|
<th>State</th>
|
||||||
|
<th>Pending Action</th>
|
||||||
|
<th>Next Stage</th>
|
||||||
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -111,7 +127,9 @@
|
|||||||
<div class="km-an">{{ row.name }}</div>
|
<div class="km-an">{{ row.name }}</div>
|
||||||
<div class="km-ai">{{ row.account }}</div>
|
<div class="km-ai">{{ row.account }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td><span class="km-b" [ngClass]="riskClass(row.risk)">{{ row.riskLabel.split(' ')[0] }}</span></td>
|
<td>
|
||||||
|
<span class="km-b" [ngClass]="riskClass(row.risk)">{{ row.riskLabel.split(' ')[0] }}</span>
|
||||||
|
</td>
|
||||||
<td>{{ row.expiry }}</td>
|
<td>{{ row.expiry }}</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="km-pbar">
|
<div class="km-pbar">
|
||||||
@@ -125,10 +143,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td><span class="km-b km-b-bl">{{ row.noticesSent }}/3</span></td>
|
<td>
|
||||||
<td><span class="km-sp" [ngClass]="stateClass(row.state)">{{ stateLabel(row.state) }}</span></td>
|
<span class="km-b km-b-bl">{{ row.noticesSent }}/3</span>
|
||||||
<td><span class="km-b km-b-am">{{ row.noticePending }}</span></td>
|
</td>
|
||||||
<td><span class="km-b km-b-or">{{ row.nextStage }}</span></td>
|
<td>
|
||||||
|
<span class="km-sp" [ngClass]="stateClass(row.state)">{{ stateLabel(row.state) }}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span class="km-b km-b-am">{{ row.noticePending }}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span class="km-b km-b-or">{{ row.nextStage }}</span>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="km-btn km-btn-ot" (click)="$event.stopPropagation(); openModal(row.id)">View</button>
|
<button class="km-btn km-btn-ot" (click)="$event.stopPropagation(); openModal(row.id)">View</button>
|
||||||
</td>
|
</td>
|
||||||
@@ -165,7 +191,10 @@
|
|||||||
<div class="km-cb">
|
<div class="km-cb">
|
||||||
<div class="km-ntl">
|
<div class="km-ntl">
|
||||||
<div class="km-nt">
|
<div class="km-nt">
|
||||||
<div class="km-nd-col"><div class="km-nd km-nd1">1</div><div class="km-nl"></div></div>
|
<div class="km-nd-col">
|
||||||
|
<div class="km-nd km-nd1">1</div>
|
||||||
|
<div class="km-nl"></div>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="km-nh">Notice 1 — Alert window opens</div>
|
<div class="km-nh">Notice 1 — Alert window opens</div>
|
||||||
<div class="km-ns">31 March 2027 · Auto-scheduled · <span class="km-ok">✓ Delivered</span></div>
|
<div class="km-ns">31 March 2027 · Auto-scheduled · <span class="km-ok">✓ Delivered</span></div>
|
||||||
@@ -176,7 +205,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="km-nt">
|
<div class="km-nt">
|
||||||
<div class="km-nd-col"><div class="km-nd km-nd2">2</div><div class="km-nl"></div></div>
|
<div class="km-nd-col">
|
||||||
|
<div class="km-nd km-nd2">2</div>
|
||||||
|
<div class="km-nl"></div>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="km-nh">Notice 2 — Follow-up</div>
|
<div class="km-nh">Notice 2 — Follow-up</div>
|
||||||
<div class="km-ns">10 April 2027 · +10 days · <span class="km-pending">⏳ Pending</span></div>
|
<div class="km-ns">10 April 2027 · +10 days · <span class="km-pending">⏳ Pending</span></div>
|
||||||
@@ -189,7 +221,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="km-nt">
|
<div class="km-nt">
|
||||||
<div class="km-nd-col"><div class="km-nd km-nd3">3</div><div class="km-nl"></div></div>
|
<div class="km-nd-col">
|
||||||
|
<div class="km-nd km-nd3">3</div>
|
||||||
|
<div class="km-nl"></div>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="km-nh">Notice 3 — Final notice</div>
|
<div class="km-nh">Notice 3 — Final notice</div>
|
||||||
<div class="km-ns">20 April 2027 · +20 days · <span class="km-fail">✗ Not dispatched</span></div>
|
<div class="km-ns">20 April 2027 · +20 days · <span class="km-fail">✗ Not dispatched</span></div>
|
||||||
@@ -198,16 +233,23 @@
|
|||||||
<span class="km-cp km-cp-mail">Email</span>
|
<span class="km-cp km-cp-mail">Email</span>
|
||||||
<span class="km-cp km-cp-ivr">IVR</span>
|
<span class="km-cp km-cp-ivr">IVR</span>
|
||||||
<span class="km-cp km-cp-post">Reg. Post</span>
|
<span class="km-cp km-cp-post">Reg. Post</span>
|
||||||
<span class="km-cp km-cp-vis">Branch Visit</span>
|
<span class="km-cp km-cp-vis">Home Visit</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="km-row-actions">
|
<div class="km-row-actions">
|
||||||
<button class="km-btn km-btn-t" (click)="toast('Notice 3 scheduled for 20 Apr 2027')">Schedule Notice 3</button>
|
<button class="km-btn km-btn-t" (click)="toast('Notice 3 scheduled for 20 Apr 2027')">
|
||||||
<button class="km-btn km-btn-ot" (click)="toast('Video KYC link added to Notice 3')">+ Video KYC Link</button>
|
Schedule Notice 3
|
||||||
|
</button>
|
||||||
|
<button class="km-btn km-btn-ot" (click)="toast('Video KYC link added to Notice 3')">
|
||||||
|
+ Video KYC Link
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="km-nt">
|
<div class="km-nt">
|
||||||
<div class="km-nd-col"><div class="km-nd km-ndf">!</div><div class="km-nl"></div></div>
|
<div class="km-nd-col">
|
||||||
|
<div class="km-nd km-ndf">!</div>
|
||||||
|
<div class="km-nl"></div>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="km-nh km-warn">Debit Freeze — if no action</div>
|
<div class="km-nh km-warn">Debit Freeze — if no action</div>
|
||||||
<div class="km-ns">30 April 2027 · Auto-triggered on expiry</div>
|
<div class="km-ns">30 April 2027 · Auto-triggered on expiry</div>
|
||||||
@@ -219,7 +261,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="km-nt">
|
<div class="km-nt">
|
||||||
<div class="km-nd-col"><div class="km-nd km-ndi">!</div><div class="km-nl"></div></div>
|
<div class="km-nd-col">
|
||||||
|
<div class="km-nd km-ndi">!</div>
|
||||||
|
<div class="km-nl"></div>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="km-nh km-warn-o">Inoperative — +60 days</div>
|
<div class="km-nh km-warn-o">Inoperative — +60 days</div>
|
||||||
<div class="km-ns">30 June 2027 · No compliance</div>
|
<div class="km-ns">30 June 2027 · No compliance</div>
|
||||||
@@ -270,7 +315,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="km-channel" (click)="toast('Branch visit toggled')">
|
<div class="km-channel" (click)="toast('Branch visit toggled')">
|
||||||
<div class="km-channel-i">🏦</div>
|
<div class="km-channel-i">🏦</div>
|
||||||
<div class="km-channel-n">Branch Visit</div>
|
<div class="km-channel-n">Home Visit</div>
|
||||||
<div class="km-channel-d">Manual</div>
|
<div class="km-channel-d">Manual</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="km-channel" (click)="toast('Video KYC toggled')">
|
<div class="km-channel" (click)="toast('Video KYC toggled')">
|
||||||
@@ -287,17 +332,28 @@
|
|||||||
<div class="km-ct">India Post Notice</div>
|
<div class="km-ct">India Post Notice</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="km-cb">
|
<div class="km-cb">
|
||||||
<div class="km-mi"><div class="km-ml">Dispatch Date</div><div class="km-mv">10 April 2027</div></div>
|
<div class="km-mi">
|
||||||
<div class="km-mi"><div class="km-ml">Reg. Post Docket No.</div><div class="km-mv km-mono">RP-BPL-20270410-443</div></div>
|
<div class="km-ml">Dispatch Date</div>
|
||||||
<div class="km-mi"><div class="km-ml">Status</div><div class="km-mv"><span class="km-b km-b-bl">In Transit</span></div></div>
|
<div class="km-mv">10 April 2027</div>
|
||||||
<button class="km-btn km-btn-g km-w" (click)="toast('Tracking RP-BPL-20270410-443 on India Post...')">Track Delivery</button>
|
</div>
|
||||||
|
<div class="km-mi">
|
||||||
|
<div class="km-ml">Reg. Post Docket No.</div>
|
||||||
|
<div class="km-mv km-mono">RP-BPL-20270410-443</div>
|
||||||
|
</div>
|
||||||
|
<div class="km-mi">
|
||||||
|
<div class="km-ml">Status</div>
|
||||||
|
<div class="km-mv"><span class="km-b km-b-bl">In Transit</span></div>
|
||||||
|
</div>
|
||||||
|
<button class="km-btn km-btn-g km-w" (click)="toast('Tracking RP-BPL-20270410-443 on India Post...')">
|
||||||
|
Track Delivery
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="km-card">
|
<div class="km-card">
|
||||||
<div class="km-ch">
|
<div class="km-ch">
|
||||||
<div class="km-ci km-ci-t"><fa-icon icon="building"></fa-icon></div>
|
<div class="km-ci km-ci-t"><fa-icon icon="building"></fa-icon></div>
|
||||||
<div class="km-ct">Branch Visit</div>
|
<div class="km-ct">Home Visit</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="km-cb">
|
<div class="km-cb">
|
||||||
<div class="km-ml">Scheduled Date</div>
|
<div class="km-ml">Scheduled Date</div>
|
||||||
@@ -334,15 +390,26 @@
|
|||||||
|
|
||||||
<div class="km-filters">
|
<div class="km-filters">
|
||||||
<select class="km-fsel">
|
<select class="km-fsel">
|
||||||
<option>All Channels</option><option>SMS</option><option>Email</option><option>IVR</option>
|
<option>All Channels</option>
|
||||||
<option>Reg. Post</option><option>Branch Visit</option><option>Video KYC</option>
|
<option>SMS</option>
|
||||||
|
<option>Email</option>
|
||||||
|
<option>IVR</option>
|
||||||
|
<option>Reg. Post</option>
|
||||||
|
<option>Home Visit</option>
|
||||||
|
<option>Video KYC</option>
|
||||||
</select>
|
</select>
|
||||||
<select class="km-fsel">
|
<select class="km-fsel">
|
||||||
<option>All Statuses</option><option>Delivered</option><option>In Transit</option>
|
<option>All Statuses</option>
|
||||||
<option>Pending</option><option>Failed</option>
|
<option>Delivered</option>
|
||||||
|
<option>In Transit</option>
|
||||||
|
<option>Pending</option>
|
||||||
|
<option>Failed</option>
|
||||||
</select>
|
</select>
|
||||||
<select class="km-fsel">
|
<select class="km-fsel">
|
||||||
<option>All Notice Nos.</option><option>Notice 1</option><option>Notice 2</option><option>Notice 3</option>
|
<option>All Notice Nos.</option>
|
||||||
|
<option>Notice 1</option>
|
||||||
|
<option>Notice 2</option>
|
||||||
|
<option>Notice 3</option>
|
||||||
</select>
|
</select>
|
||||||
<input class="km-finp" type="text" placeholder="Search account, name or reference..." />
|
<input class="km-finp" type="text" placeholder="Search account, name or reference..." />
|
||||||
<button class="km-btn km-btn-t" (click)="toast('Filters applied')">Apply</button>
|
<button class="km-btn km-btn-t" (click)="toast('Filters applied')">Apply</button>
|
||||||
@@ -357,15 +424,24 @@
|
|||||||
<table class="km-tbl">
|
<table class="km-tbl">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>#</th><th>Account / Customer</th><th>Notice</th><th>Channel</th>
|
<th>#</th>
|
||||||
<th>Dispatched</th><th>Reference / Docket</th><th>Delivery</th>
|
<th>Account / Customer</th>
|
||||||
<th>Client Action</th><th>Officer</th>
|
<th>Notice</th>
|
||||||
|
<th>Channel</th>
|
||||||
|
<th>Dispatched</th>
|
||||||
|
<th>Reference / Docket</th>
|
||||||
|
<th>Delivery</th>
|
||||||
|
<th>Client Action</th>
|
||||||
|
<th>Officer</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr (click)="openModal('rajesh')">
|
<tr (click)="openModal('rajesh')">
|
||||||
<td class="km-num">001</td>
|
<td class="km-num">001</td>
|
||||||
<td><div class="km-an">Rajesh K. Sharma</div><div class="km-ai">ACC-BPL-2024-00847</div></td>
|
<td>
|
||||||
|
<div class="km-an">Rajesh K. Sharma</div>
|
||||||
|
<div class="km-ai">ACC-BPL-2024-00847</div>
|
||||||
|
</td>
|
||||||
<td><span class="km-b km-b-bl">Notice 1</span></td>
|
<td><span class="km-b km-b-bl">Notice 1</span></td>
|
||||||
<td>SMS + Email</td>
|
<td>SMS + Email</td>
|
||||||
<td>31 Mar 2027</td>
|
<td>31 Mar 2027</td>
|
||||||
@@ -376,7 +452,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr (click)="openModal('rajesh')">
|
<tr (click)="openModal('rajesh')">
|
||||||
<td class="km-num">002</td>
|
<td class="km-num">002</td>
|
||||||
<td><div class="km-an">Rajesh K. Sharma</div><div class="km-ai">ACC-BPL-2024-00847</div></td>
|
<td>
|
||||||
|
<div class="km-an">Rajesh K. Sharma</div>
|
||||||
|
<div class="km-ai">ACC-BPL-2024-00847</div>
|
||||||
|
</td>
|
||||||
<td><span class="km-b km-b-am">Notice 2</span></td>
|
<td><span class="km-b km-b-am">Notice 2</span></td>
|
||||||
<td>Reg. Post + IVR</td>
|
<td>Reg. Post + IVR</td>
|
||||||
<td>10 Apr 2027</td>
|
<td>10 Apr 2027</td>
|
||||||
@@ -387,7 +466,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr (click)="openModal('priya')">
|
<tr (click)="openModal('priya')">
|
||||||
<td class="km-num">003</td>
|
<td class="km-num">003</td>
|
||||||
<td><div class="km-an">Priya Malhotra</div><div class="km-ai">ACC-BPL-2021-00231</div></td>
|
<td>
|
||||||
|
<div class="km-an">Priya Malhotra</div>
|
||||||
|
<div class="km-ai">ACC-BPL-2021-00231</div>
|
||||||
|
</td>
|
||||||
<td><span class="km-b km-b-bl">Notice 1</span></td>
|
<td><span class="km-b km-b-bl">Notice 1</span></td>
|
||||||
<td>SMS + Email</td>
|
<td>SMS + Email</td>
|
||||||
<td>10 Mar 2027</td>
|
<td>10 Mar 2027</td>
|
||||||
@@ -398,7 +480,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr (click)="openModal('priya')">
|
<tr (click)="openModal('priya')">
|
||||||
<td class="km-num">004</td>
|
<td class="km-num">004</td>
|
||||||
<td><div class="km-an">Priya Malhotra</div><div class="km-ai">ACC-BPL-2021-00231</div></td>
|
<td>
|
||||||
|
<div class="km-an">Priya Malhotra</div>
|
||||||
|
<div class="km-ai">ACC-BPL-2021-00231</div>
|
||||||
|
</td>
|
||||||
<td><span class="km-b km-b-am">Notice 2</span></td>
|
<td><span class="km-b km-b-am">Notice 2</span></td>
|
||||||
<td>Reg. Post</td>
|
<td>Reg. Post</td>
|
||||||
<td>20 Mar 2027</td>
|
<td>20 Mar 2027</td>
|
||||||
@@ -409,9 +494,12 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr (click)="openModal('priya')">
|
<tr (click)="openModal('priya')">
|
||||||
<td class="km-num">005</td>
|
<td class="km-num">005</td>
|
||||||
<td><div class="km-an">Priya Malhotra</div><div class="km-ai">ACC-BPL-2021-00231</div></td>
|
<td>
|
||||||
|
<div class="km-an">Priya Malhotra</div>
|
||||||
|
<div class="km-ai">ACC-BPL-2021-00231</div>
|
||||||
|
</td>
|
||||||
<td><span class="km-b km-b-or">Notice 3</span></td>
|
<td><span class="km-b km-b-or">Notice 3</span></td>
|
||||||
<td>Branch Visit</td>
|
<td>Home Visit</td>
|
||||||
<td>30 Mar 2027</td>
|
<td>30 Mar 2027</td>
|
||||||
<td><span class="km-ref">VIS-BPL-20270330-012</span></td>
|
<td><span class="km-ref">VIS-BPL-20270330-012</span></td>
|
||||||
<td><span class="km-del km-d-ok">✓ Done</span></td>
|
<td><span class="km-del km-d-ok">✓ Done</span></td>
|
||||||
@@ -420,7 +508,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr (click)="openModal('suresh')">
|
<tr (click)="openModal('suresh')">
|
||||||
<td class="km-num">006</td>
|
<td class="km-num">006</td>
|
||||||
<td><div class="km-an">Suresh Patel</div><div class="km-ai">ACC-BPL-2019-00112</div></td>
|
<td>
|
||||||
|
<div class="km-an">Suresh Patel</div>
|
||||||
|
<div class="km-ai">ACC-BPL-2019-00112</div>
|
||||||
|
</td>
|
||||||
<td><span class="km-b km-b-or">Notice 3</span></td>
|
<td><span class="km-b km-b-or">Notice 3</span></td>
|
||||||
<td>Video KYC</td>
|
<td>Video KYC</td>
|
||||||
<td>5 Feb 2027</td>
|
<td>5 Feb 2027</td>
|
||||||
@@ -454,19 +545,29 @@
|
|||||||
|
|
||||||
<div class="km-sc-row">
|
<div class="km-sc-row">
|
||||||
<div class="km-sc km-sc-ac" (click)="toast('Filtering: Active')">
|
<div class="km-sc km-sc-ac" (click)="toast('Filtering: Active')">
|
||||||
<div class="km-sc-l">Active</div><div class="km-sc-n">1,847</div><div class="km-sc-d">KYC valid</div>
|
<div class="km-sc-l">Active</div>
|
||||||
|
<div class="km-sc-n">1,847</div>
|
||||||
|
<div class="km-sc-d">KYC valid</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="km-sc km-sc-al" (click)="toast('Filtering: Alert window')">
|
<div class="km-sc km-sc-al" (click)="toast('Filtering: Alert window')">
|
||||||
<div class="km-sc-l">Alert Window</div><div class="km-sc-n">47</div><div class="km-sc-d">Expiring < 30d</div>
|
<div class="km-sc-l">Alert Window</div>
|
||||||
|
<div class="km-sc-n">47</div>
|
||||||
|
<div class="km-sc-d">Expiring < 30d</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="km-sc km-sc-fr" (click)="toast('Filtering: Debit Freeze')">
|
<div class="km-sc km-sc-fr" (click)="toast('Filtering: Debit Freeze')">
|
||||||
<div class="km-sc-l">Debit Freeze</div><div class="km-sc-n">23</div><div class="km-sc-d">Debits blocked</div>
|
<div class="km-sc-l">Debit Freeze</div>
|
||||||
|
<div class="km-sc-n">23</div>
|
||||||
|
<div class="km-sc-d">Debits blocked</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="km-sc km-sc-in" (click)="toast('Filtering: Inoperative')">
|
<div class="km-sc km-sc-in" (click)="toast('Filtering: Inoperative')">
|
||||||
<div class="km-sc-l">Inoperative</div><div class="km-sc-n">8</div><div class="km-sc-d">All txns blocked</div>
|
<div class="km-sc-l">Inoperative</div>
|
||||||
|
<div class="km-sc-n">8</div>
|
||||||
|
<div class="km-sc-d">All txns blocked</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="km-sc km-sc-do" (click)="toast('Filtering: Dormant')">
|
<div class="km-sc km-sc-do" (click)="toast('Filtering: Dormant')">
|
||||||
<div class="km-sc-l">Dormant</div><div class="km-sc-n">3</div><div class="km-sc-d">RBI reportable</div>
|
<div class="km-sc-l">Dormant</div>
|
||||||
|
<div class="km-sc-n">3</div>
|
||||||
|
<div class="km-sc-d">RBI reportable</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -478,20 +579,28 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="km-cb-flush">
|
<div class="km-cb-flush">
|
||||||
<div class="km-rule">
|
<div class="km-rule">
|
||||||
<div class="km-rule-h"><span class="km-rule-t">Active → Debit Freeze</span><span class="km-b km-b-gr">Enabled</span></div>
|
<div class="km-rule-h">
|
||||||
<div class="km-rule-d">KYC expires + 3 notices sent + no response → debits blocked, credits allowed</div>
|
<span class="km-rule-t">Active → Debit Freeze</span><span class="km-b km-b-gr">Enabled</span>
|
||||||
|
</div>
|
||||||
|
<div class="km-rule-d">
|
||||||
|
KYC expires + 3 notices sent + no response → debits blocked, credits allowed
|
||||||
|
</div>
|
||||||
<div class="km-rule-tags">
|
<div class="km-rule-tags">
|
||||||
<span class="km-b km-b-gy">Window: 31 Mar – 30 Apr</span>
|
<span class="km-b km-b-gy">Window: 31 Mar – 30 Apr</span>
|
||||||
<span class="km-b km-b-gy">3/3 notices</span>
|
<span class="km-b km-b-gy">3/3 notices</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="km-rule">
|
<div class="km-rule">
|
||||||
<div class="km-rule-h"><span class="km-rule-t">Debit Freeze → Inoperative</span><span class="km-b km-b-gr">Enabled</span></div>
|
<div class="km-rule-h">
|
||||||
|
<span class="km-rule-t">Debit Freeze → Inoperative</span><span class="km-b km-b-gr">Enabled</span>
|
||||||
|
</div>
|
||||||
<div class="km-rule-d">+60 days from expiry, still unresolved → all transactions blocked</div>
|
<div class="km-rule-d">+60 days from expiry, still unresolved → all transactions blocked</div>
|
||||||
<div class="km-rule-tags"><span class="km-b km-b-gy">Apr 30 – Jun 30</span></div>
|
<div class="km-rule-tags"><span class="km-b km-b-gy">Apr 30 – Jun 30</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="km-rule km-rule-last">
|
<div class="km-rule km-rule-last">
|
||||||
<div class="km-rule-h"><span class="km-rule-t">Inoperative → Dormant</span><span class="km-b km-b-gr">Enabled</span></div>
|
<div class="km-rule-h">
|
||||||
|
<span class="km-rule-t">Inoperative → Dormant</span><span class="km-b km-b-gr">Enabled</span>
|
||||||
|
</div>
|
||||||
<div class="km-rule-d">+150 days from expiry → dormant, RBI Dormant Account reporting triggered</div>
|
<div class="km-rule-d">+150 days from expiry → dormant, RBI Dormant Account reporting triggered</div>
|
||||||
<div class="km-rule-tags">
|
<div class="km-rule-tags">
|
||||||
<span class="km-b km-b-gy">Jun 30 – Sep 30</span>
|
<span class="km-b km-b-gy">Jun 30 – Sep 30</span>
|
||||||
@@ -533,7 +642,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="km-warn-box">
|
<div class="km-warn-box">
|
||||||
<div class="km-warn-t">⚠ Maker-Checker Required</div>
|
<div class="km-warn-t">⚠ Maker-Checker Required</div>
|
||||||
<div class="km-warn-d">All manual changes require second officer approval and are logged in audit inventory.</div>
|
<div class="km-warn-d">
|
||||||
|
All manual changes require second officer approval and are logged in audit inventory.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -547,35 +658,64 @@
|
|||||||
</div>
|
</div>
|
||||||
<table class="km-tbl">
|
<table class="km-tbl">
|
||||||
<thead>
|
<thead>
|
||||||
<tr><th>Account</th><th>From</th><th>To</th><th>Trigger</th><th>Date</th><th>By</th><th>Action</th></tr>
|
<tr>
|
||||||
|
<th>Account</th>
|
||||||
|
<th>From</th>
|
||||||
|
<th>To</th>
|
||||||
|
<th>Trigger</th>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>By</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr (click)="openModal('priya')">
|
<tr (click)="openModal('priya')">
|
||||||
<td><div class="km-an">Priya Malhotra</div><div class="km-ai">ACC-BPL-2021-00231</div></td>
|
<td>
|
||||||
|
<div class="km-an">Priya Malhotra</div>
|
||||||
|
<div class="km-ai">ACC-BPL-2021-00231</div>
|
||||||
|
</td>
|
||||||
<td><span class="km-sp km-sp-ac">Active</span></td>
|
<td><span class="km-sp km-sp-ac">Active</span></td>
|
||||||
<td><span class="km-sp km-sp-fr">Debit Freeze</span></td>
|
<td><span class="km-sp km-sp-fr">Debit Freeze</span></td>
|
||||||
<td><span class="km-b km-b-am">Auto — KYC Expired</span></td>
|
<td><span class="km-b km-b-am">Auto — KYC Expired</span></td>
|
||||||
<td>10 Apr 2027</td>
|
<td>10 Apr 2027</td>
|
||||||
<td class="km-small">Scheduler</td>
|
<td class="km-small">Scheduler</td>
|
||||||
<td><button class="km-btn km-btn-ot" (click)="$event.stopPropagation(); toast('Unfreeze initiated')">Unfreeze</button></td>
|
<td>
|
||||||
|
<button class="km-btn km-btn-ot" (click)="$event.stopPropagation(); toast('Unfreeze initiated')">
|
||||||
|
Unfreeze
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr (click)="openModal('suresh')">
|
<tr (click)="openModal('suresh')">
|
||||||
<td><div class="km-an">Suresh Patel</div><div class="km-ai">ACC-BPL-2019-00112</div></td>
|
<td>
|
||||||
|
<div class="km-an">Suresh Patel</div>
|
||||||
|
<div class="km-ai">ACC-BPL-2019-00112</div>
|
||||||
|
</td>
|
||||||
<td><span class="km-sp km-sp-fr">Debit Freeze</span></td>
|
<td><span class="km-sp km-sp-fr">Debit Freeze</span></td>
|
||||||
<td><span class="km-sp km-sp-in">Inoperative</span></td>
|
<td><span class="km-sp km-sp-in">Inoperative</span></td>
|
||||||
<td><span class="km-b km-b-or">Auto — 60d elapsed</span></td>
|
<td><span class="km-b km-b-or">Auto — 60d elapsed</span></td>
|
||||||
<td>15 May 2027</td>
|
<td>15 May 2027</td>
|
||||||
<td class="km-small">Scheduler</td>
|
<td class="km-small">Scheduler</td>
|
||||||
<td><button class="km-btn km-btn-g" (click)="$event.stopPropagation(); toast('Override needs approval')">Override</button></td>
|
<td>
|
||||||
|
<button class="km-btn km-btn-g" (click)="$event.stopPropagation(); toast('Override needs approval')">
|
||||||
|
Override
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr (click)="openModal('kavitha')">
|
<tr (click)="openModal('kavitha')">
|
||||||
<td><div class="km-an">Kavitha Nair</div><div class="km-ai">ACC-BPL-2018-00088</div></td>
|
<td>
|
||||||
|
<div class="km-an">Kavitha Nair</div>
|
||||||
|
<div class="km-ai">ACC-BPL-2018-00088</div>
|
||||||
|
</td>
|
||||||
<td><span class="km-sp km-sp-in">Inoperative</span></td>
|
<td><span class="km-sp km-sp-in">Inoperative</span></td>
|
||||||
<td><span class="km-sp km-sp-do">Dormant</span></td>
|
<td><span class="km-sp km-sp-do">Dormant</span></td>
|
||||||
<td><span class="km-b km-b-re">Auto — 150d elapsed</span></td>
|
<td><span class="km-b km-b-re">Auto — 150d elapsed</span></td>
|
||||||
<td>1 Jun 2027</td>
|
<td>1 Jun 2027</td>
|
||||||
<td class="km-small">Scheduler</td>
|
<td class="km-small">Scheduler</td>
|
||||||
<td><button class="km-btn km-btn-g" (click)="$event.stopPropagation(); toast('Reversal needs RM + RBI')">Reverse</button></td>
|
<td>
|
||||||
|
<button class="km-btn km-btn-g" (click)="$event.stopPropagation(); toast('Reversal needs RM + RBI')">
|
||||||
|
Reverse
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -600,11 +740,21 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="km-mbody">
|
<div class="km-mbody">
|
||||||
<div class="km-mtab-bar">
|
<div class="km-mtab-bar">
|
||||||
<button class="km-mtab" [class.active]="modalTab === 'overview'" (click)="showMTab('overview')">Overview</button>
|
<button class="km-mtab" [class.active]="modalTab === 'overview'" (click)="showMTab('overview')">
|
||||||
<button class="km-mtab" [class.active]="modalTab === 'timeline'" (click)="showMTab('timeline')">Alert Timeline</button>
|
Overview
|
||||||
<button class="km-mtab" [class.active]="modalTab === 'notices'" (click)="showMTab('notices')">Notices Sent</button>
|
</button>
|
||||||
<button class="km-mtab" [class.active]="modalTab === 'evidence'" (click)="showMTab('evidence')">Evidence</button>
|
<button class="km-mtab" [class.active]="modalTab === 'timeline'" (click)="showMTab('timeline')">
|
||||||
<button class="km-mtab" [class.active]="modalTab === 'action'" (click)="showMTab('action')">Take Action</button>
|
Alert Timeline
|
||||||
|
</button>
|
||||||
|
<button class="km-mtab" [class.active]="modalTab === 'notices'" (click)="showMTab('notices')">
|
||||||
|
Notices Sent
|
||||||
|
</button>
|
||||||
|
<button class="km-mtab" [class.active]="modalTab === 'evidence'" (click)="showMTab('evidence')">
|
||||||
|
Evidence
|
||||||
|
</button>
|
||||||
|
<button class="km-mtab" [class.active]="modalTab === 'action'" (click)="showMTab('action')">
|
||||||
|
Take Action
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- OVERVIEW -->
|
<!-- OVERVIEW -->
|
||||||
@@ -623,36 +773,86 @@
|
|||||||
<div class="km-nb-icon">⚡</div>
|
<div class="km-nb-icon">⚡</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="km-nb-title">{{ stateLabel(current.state) }} — {{ current.daysLeft }} days to expiry</div>
|
<div class="km-nb-title">{{ stateLabel(current.state) }} — {{ current.daysLeft }} days to expiry</div>
|
||||||
<div class="km-nb-sub">Next pending: <strong>{{ current.noticePending }}</strong>. Next stage: <strong>{{ current.nextStage }}</strong>.</div>
|
<div class="km-nb-sub">
|
||||||
|
Next pending: <strong>{{ current.noticePending }}</strong
|
||||||
|
>. Next stage: <strong>{{ current.nextStage }}</strong
|
||||||
|
>.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="km-mstat-row">
|
<div class="km-mstat-row">
|
||||||
<div class="km-mstat"><div class="km-mstat-n">{{ current.noticesSent }}</div><div class="km-mstat-l">Notices Sent</div></div>
|
<div class="km-mstat">
|
||||||
<div class="km-mstat"><div class="km-mstat-n">{{ noticesPending(current) }}</div><div class="km-mstat-l">Notices Pending</div></div>
|
<div class="km-mstat-n">{{ current.noticesSent }}</div>
|
||||||
<div class="km-mstat"><div class="km-mstat-n">{{ current.actionTaken.length }}</div><div class="km-mstat-l">Actions Taken</div></div>
|
<div class="km-mstat-l">Notices Sent</div>
|
||||||
<div class="km-mstat"><div class="km-mstat-n">{{ current.pendingActions.length }}</div><div class="km-mstat-l">Pending Actions</div></div>
|
</div>
|
||||||
|
<div class="km-mstat">
|
||||||
|
<div class="km-mstat-n">{{ noticesPending(current) }}</div>
|
||||||
|
<div class="km-mstat-l">Notices Pending</div>
|
||||||
|
</div>
|
||||||
|
<div class="km-mstat">
|
||||||
|
<div class="km-mstat-n">{{ current.actionTaken.length }}</div>
|
||||||
|
<div class="km-mstat-l">Actions Taken</div>
|
||||||
|
</div>
|
||||||
|
<div class="km-mstat">
|
||||||
|
<div class="km-mstat-n">{{ current.pendingActions.length }}</div>
|
||||||
|
<div class="km-mstat-l">Pending Actions</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="km-r2">
|
<div class="km-r2">
|
||||||
<div>
|
<div>
|
||||||
<div class="km-slbl">KYC Information</div>
|
<div class="km-slbl">KYC Information</div>
|
||||||
<div class="km-mg">
|
<div class="km-mg">
|
||||||
<div class="km-mi"><div class="km-ml">PAN</div><div class="km-mv km-mono">{{ current.kyc.pan }}</div></div>
|
<div class="km-mi">
|
||||||
<div class="km-mi"><div class="km-ml">PAN Status</div><div class="km-mv"><span class="km-b km-b-gr">{{ current.kyc.panStatus }}</span></div></div>
|
<div class="km-ml">PAN</div>
|
||||||
<div class="km-mi"><div class="km-ml">Aadhaar</div><div class="km-mv km-mono">{{ current.kyc.aadhaar }}</div></div>
|
<div class="km-mv km-mono">{{ current.kyc.pan }}</div>
|
||||||
<div class="km-mi"><div class="km-ml">Aadhaar Status</div><div class="km-mv"><span class="km-b km-b-gr">{{ current.kyc.aadhaarStatus }}</span></div></div>
|
</div>
|
||||||
<div class="km-mi"><div class="km-ml">KYC Validity</div><div class="km-mv">{{ current.kyc.validity }}</div></div>
|
<div class="km-mi">
|
||||||
<div class="km-mi"><div class="km-ml">Expiry Date</div><div class="km-mv km-red">{{ current.expiry }}</div></div>
|
<div class="km-ml">PAN Status</div>
|
||||||
|
<div class="km-mv">
|
||||||
|
<span class="km-b km-b-gr">{{ current.kyc.panStatus }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="km-mi">
|
||||||
|
<div class="km-ml">Aadhaar</div>
|
||||||
|
<div class="km-mv km-mono">{{ current.kyc.aadhaar }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="km-mi">
|
||||||
|
<div class="km-ml">Aadhaar Status</div>
|
||||||
|
<div class="km-mv">
|
||||||
|
<span class="km-b km-b-gr">{{ current.kyc.aadhaarStatus }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="km-mi">
|
||||||
|
<div class="km-ml">KYC Validity</div>
|
||||||
|
<div class="km-mv">{{ current.kyc.validity }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="km-mi">
|
||||||
|
<div class="km-ml">Expiry Date</div>
|
||||||
|
<div class="km-mv km-red">{{ current.expiry }}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="km-slbl">Contact Details</div>
|
<div class="km-slbl">Contact Details</div>
|
||||||
<div class="km-mg">
|
<div class="km-mg">
|
||||||
<div class="km-mi"><div class="km-ml">Mobile</div><div class="km-mv">{{ current.contact.mobile }}</div></div>
|
<div class="km-mi">
|
||||||
<div class="km-mi"><div class="km-ml">Email</div><div class="km-mv km-small">{{ current.contact.email }}</div></div>
|
<div class="km-ml">Mobile</div>
|
||||||
<div class="km-mi km-mi-span"><div class="km-ml">Address</div><div class="km-mv km-small">{{ current.contact.address }}</div></div>
|
<div class="km-mv">{{ current.contact.mobile }}</div>
|
||||||
<div class="km-mi"><div class="km-ml">Branch</div><div class="km-mv">{{ current.contact.branch }}</div></div>
|
</div>
|
||||||
|
<div class="km-mi">
|
||||||
|
<div class="km-ml">Email</div>
|
||||||
|
<div class="km-mv km-small">{{ current.contact.email }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="km-mi km-mi-span">
|
||||||
|
<div class="km-ml">Address</div>
|
||||||
|
<div class="km-mv km-small">{{ current.contact.address }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="km-mi">
|
||||||
|
<div class="km-ml">Branch</div>
|
||||||
|
<div class="km-mv">{{ current.contact.branch }}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -688,22 +888,44 @@
|
|||||||
<div class="km-slbl">All Notices Dispatched</div>
|
<div class="km-slbl">All Notices Dispatched</div>
|
||||||
<table class="km-tbl">
|
<table class="km-tbl">
|
||||||
<thead>
|
<thead>
|
||||||
<tr><th>#</th><th>Notice</th><th>Channel</th><th>Date</th><th>Reference</th><th>Delivery</th><th>Response</th></tr>
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th>Notice</th>
|
||||||
|
<th>Channel</th>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Reference</th>
|
||||||
|
<th>Delivery</th>
|
||||||
|
<th>Response</th>
|
||||||
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@for (n of current.notices; track n.ref; let i = $index) {
|
@for (n of current.notices; track n.ref; let i = $index) {
|
||||||
<tr>
|
<tr>
|
||||||
<td class="km-num">{{ i + 1 }}</td>
|
<td class="km-num">{{ i + 1 }}</td>
|
||||||
<td><span class="km-b" [ngClass]="i === 0 ? 'km-b-bl' : i === 1 ? 'km-b-am' : 'km-b-or'">{{ n.no }}</span></td>
|
<td>
|
||||||
|
<span class="km-b" [ngClass]="i === 0 ? 'km-b-bl' : i === 1 ? 'km-b-am' : 'km-b-or'">{{
|
||||||
|
n.no
|
||||||
|
}}</span>
|
||||||
|
</td>
|
||||||
<td class="km-small">{{ n.channel }}</td>
|
<td class="km-small">{{ n.channel }}</td>
|
||||||
<td>{{ n.date }}</td>
|
<td>{{ n.date }}</td>
|
||||||
<td><span class="km-ref">{{ n.ref }}</span></td>
|
<td>
|
||||||
<td><span class="km-del" [ngClass]="deliveryClass(n.delivery)">{{ n.delivery }}</span></td>
|
<span class="km-ref">{{ n.ref }}</span>
|
||||||
<td><span class="km-del" [ngClass]="responseClass(n.response)">{{ n.response }}</span></td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<span class="km-del" [ngClass]="deliveryClass(n.delivery)">{{ n.delivery }}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span class="km-del" [ngClass]="responseClass(n.response)">{{ n.response }}</span>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
@if (noticesPending(current) > 0) {
|
@if (noticesPending(current) > 0) {
|
||||||
<tr><td colspan="7" class="km-pending-row">⏳ {{ noticesPending(current) }} notice(s) still pending dispatch</td></tr>
|
<tr>
|
||||||
|
<td colspan="7" class="km-pending-row">
|
||||||
|
⏳ {{ noticesPending(current) }} notice(s) still pending dispatch
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -718,28 +940,55 @@
|
|||||||
<div class="km-empty-s">Evidence is captured during branch visits or video KYC sessions.</div>
|
<div class="km-empty-s">Evidence is captured during branch visits or video KYC sessions.</div>
|
||||||
</div>
|
</div>
|
||||||
} @else {
|
} @else {
|
||||||
<div class="km-slbl">{{ current.evidence.type === 'visit' ? 'Branch Visit Evidence' : 'Video KYC Session Log' }}</div>
|
<div class="km-slbl">
|
||||||
|
{{ current.evidence.type === 'visit' ? 'Home Visit Evidence' : 'Video KYC Session Log' }}
|
||||||
|
</div>
|
||||||
<div class="km-r2 km-mb">
|
<div class="km-r2 km-mb">
|
||||||
<div class="km-mi"><div class="km-ml">Date</div><div class="km-mv">{{ current.evidence.date }}</div></div>
|
<div class="km-mi">
|
||||||
<div class="km-mi"><div class="km-ml">Officer / Agent</div><div class="km-mv">{{ current.evidence.officer }}</div></div>
|
<div class="km-ml">Date</div>
|
||||||
|
<div class="km-mv">{{ current.evidence.date }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="km-mi">
|
||||||
|
<div class="km-ml">Officer / Agent</div>
|
||||||
|
<div class="km-mv">{{ current.evidence.officer }}</div>
|
||||||
|
</div>
|
||||||
@if (current.evidence.type === 'visit') {
|
@if (current.evidence.type === 'visit') {
|
||||||
<div class="km-mi"><div class="km-ml">GPS Coordinates</div><div class="km-mv km-mono">{{ current.evidence.gps }}</div></div>
|
<div class="km-mi">
|
||||||
<div class="km-mi"><div class="km-ml">Location</div><div class="km-mv km-small">{{ current.evidence.location }}</div></div>
|
<div class="km-ml">GPS Coordinates</div>
|
||||||
|
<div class="km-mv km-mono">{{ current.evidence.gps }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="km-mi">
|
||||||
|
<div class="km-ml">Location</div>
|
||||||
|
<div class="km-mv km-small">{{ current.evidence.location }}</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
<div class="km-mi"><div class="km-ml">Reference / Docket</div><div class="km-mv km-mono">{{ current.evidence.docket || current.evidence.ref }}</div></div>
|
<div class="km-mi">
|
||||||
<div class="km-mi"><div class="km-ml">Outcome</div><div class="km-mv"><span class="km-del km-d-fa">No Compliance</span></div></div>
|
<div class="km-ml">Reference / Docket</div>
|
||||||
|
<div class="km-mv km-mono">{{ current.evidence.docket || current.evidence.ref }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="km-mi">
|
||||||
|
<div class="km-ml">Outcome</div>
|
||||||
|
<div class="km-mv"><span class="km-del km-d-fa">No Compliance</span></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if (current.evidence.type === 'visit') {
|
@if (current.evidence.type === 'visit') {
|
||||||
<div class="km-slbl">Map Placeholder</div>
|
<div class="km-slbl">Map Placeholder</div>
|
||||||
<div class="km-map">{{ current.evidence.gps }}<div class="km-small">{{ current.evidence.location }}</div></div>
|
<div class="km-map">
|
||||||
|
{{ current.evidence.gps }}
|
||||||
|
<div class="km-small">{{ current.evidence.location }}</div>
|
||||||
|
</div>
|
||||||
<div class="km-slbl">Photo Evidence</div>
|
<div class="km-slbl">Photo Evidence</div>
|
||||||
<div class="km-photo">Visit photo uploaded · Tap to view</div>
|
<div class="km-photo">Visit photo uploaded · Tap to view</div>
|
||||||
}
|
}
|
||||||
<div class="km-slbl">Officer Notes</div>
|
<div class="km-slbl">Officer Notes</div>
|
||||||
<div class="km-notes">{{ current.evidence.outcome }}</div>
|
<div class="km-notes">{{ current.evidence.outcome }}</div>
|
||||||
<div class="km-row-actions">
|
<div class="km-row-actions">
|
||||||
<button class="km-btn km-btn-t" (click)="toast('Downloading evidence package...')">Download Package</button>
|
<button class="km-btn km-btn-t" (click)="toast('Downloading evidence package...')">
|
||||||
<button class="km-btn km-btn-g" (click)="toast('Sharing with RBI audit team...')">Share for Audit</button>
|
Download Package
|
||||||
|
</button>
|
||||||
|
<button class="km-btn km-btn-g" (click)="toast('Sharing with RBI audit team...')">
|
||||||
|
Share for Audit
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -754,7 +1003,7 @@
|
|||||||
<div class="km-action-t">{{ action }}</div>
|
<div class="km-action-t">{{ action }}</div>
|
||||||
<div class="km-action-d">Initiate via available channels</div>
|
<div class="km-action-d">Initiate via available channels</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="km-btn km-btn-t" (click)="toast(action + ' initiated for ' + current.name)">Take Action</button>
|
<button class="km-btn km-btn-t" (click)="takeAction(action)">Take Action</button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -764,6 +1013,158 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<!-- HOME VISIT SCHEDULE DIALOG -->
|
||||||
|
@if (homeVisitOpen && current) {
|
||||||
|
<div class="km-overlay" (click)="closeHomeVisitDialog()">
|
||||||
|
<div class="km-modal hv-modal" (click)="$event.stopPropagation()">
|
||||||
|
<div class="km-mh">
|
||||||
|
<div class="km-mh-av">{{ current.av }}</div>
|
||||||
|
<div>
|
||||||
|
<div class="km-mh-name">Schedule Home Visit</div>
|
||||||
|
<div class="km-mh-meta">{{ current.name }} · {{ current.account }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="km-mclose" (click)="closeHomeVisitDialog()">✕</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="km-mbody hv-body">
|
||||||
|
<div class="hv-addr">
|
||||||
|
<div class="hv-addr-label">Visit Address</div>
|
||||||
|
<div class="hv-addr-name">{{ current.name }}</div>
|
||||||
|
<div class="hv-addr-text">{{ current.contact.address }}</div>
|
||||||
|
<div class="hv-addr-branch">Branch: {{ current.contact.branch }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hv-row">
|
||||||
|
<label class="hv-label">Bank Officer<span class="hv-req">*</span></label>
|
||||||
|
<select class="hv-input" [(ngModel)]="homeVisitOfficer">
|
||||||
|
<option value="" disabled>Select an officer…</option>
|
||||||
|
@for (officer of bankOfficers; track officer) {
|
||||||
|
<option [value]="officer">{{ officer }}</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hv-row">
|
||||||
|
<label class="hv-label">Visit Date & Time<span class="hv-req">*</span></label>
|
||||||
|
<input type="datetime-local" class="hv-input" [(ngModel)]="homeVisitDateTime" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hv-row">
|
||||||
|
<label class="hv-label">Notes (optional)</label>
|
||||||
|
<textarea
|
||||||
|
class="hv-input hv-textarea"
|
||||||
|
rows="2"
|
||||||
|
placeholder="Any specific instructions for the officer…"
|
||||||
|
[(ngModel)]="homeVisitNote"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hv-footer">
|
||||||
|
<button class="km-btn" (click)="closeHomeVisitDialog()">Cancel</button>
|
||||||
|
<button
|
||||||
|
class="km-btn km-btn-t"
|
||||||
|
[disabled]="!homeVisitOfficer || !homeVisitDateTime"
|
||||||
|
(click)="saveHomeVisit()"
|
||||||
|
>
|
||||||
|
Save Visit
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<!-- VIDEO KYC LINK DIALOG -->
|
||||||
|
@if (vkycOpen && current) {
|
||||||
|
<div class="km-overlay" (click)="closeVkycDialog()">
|
||||||
|
<div class="km-modal hv-modal" (click)="$event.stopPropagation()">
|
||||||
|
<div class="km-mh">
|
||||||
|
<div class="km-mh-av">{{ current.av }}</div>
|
||||||
|
<div>
|
||||||
|
<div class="km-mh-name">Send Video KYC Link</div>
|
||||||
|
<div class="km-mh-meta">{{ current.name }} · {{ current.account }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="km-mclose" (click)="closeVkycDialog()">✕</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="km-mbody hv-body">
|
||||||
|
<div class="hv-addr">
|
||||||
|
<div class="hv-addr-label">Customer Contact</div>
|
||||||
|
<div class="hv-addr-name">{{ current.name }}</div>
|
||||||
|
<div class="hv-addr-text">
|
||||||
|
<fa-icon icon="mobile-alt" class="vkyc-ic"></fa-icon> {{ current.contact.mobile }}
|
||||||
|
</div>
|
||||||
|
<div class="hv-addr-text">
|
||||||
|
<fa-icon icon="envelope" class="vkyc-ic"></fa-icon> {{ current.contact.email }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hv-row">
|
||||||
|
<label class="hv-label">Send Via<span class="hv-req">*</span></label>
|
||||||
|
<div class="vkyc-chans">
|
||||||
|
<label class="vkyc-chan">
|
||||||
|
<input type="checkbox" [(ngModel)]="vkycChannels.sms" />
|
||||||
|
<span>SMS</span>
|
||||||
|
</label>
|
||||||
|
<label class="vkyc-chan">
|
||||||
|
<input type="checkbox" [(ngModel)]="vkycChannels.email" />
|
||||||
|
<span>Email</span>
|
||||||
|
</label>
|
||||||
|
<label class="vkyc-chan">
|
||||||
|
<input type="checkbox" [(ngModel)]="vkycChannels.whatsapp" />
|
||||||
|
<span>WhatsApp</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hv-row">
|
||||||
|
<label class="hv-label">Assign KYC Officer<span class="hv-req">*</span></label>
|
||||||
|
<select class="hv-input" [(ngModel)]="vkycOfficer">
|
||||||
|
<option value="" disabled>Select an officer…</option>
|
||||||
|
@for (officer of bankOfficers; track officer) {
|
||||||
|
<option [value]="officer">{{ officer }}</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hv-row">
|
||||||
|
<label class="hv-label">Link Expiry<span class="hv-req">*</span></label>
|
||||||
|
<input type="datetime-local" class="hv-input" [(ngModel)]="vkycExpiry" />
|
||||||
|
<div class="vkyc-hint">Default: 48 hours (RBI Video-based KYC norms)</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hv-row">
|
||||||
|
<label class="hv-label">Session Link Preview</label>
|
||||||
|
<div class="vkyc-link">
|
||||||
|
<span class="vkyc-link-text">{{ vkycLink }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hv-row">
|
||||||
|
<label class="hv-label">Custom Message (optional)</label>
|
||||||
|
<textarea
|
||||||
|
class="hv-input hv-textarea"
|
||||||
|
rows="2"
|
||||||
|
placeholder="e.g. Please complete your Video KYC at your earliest convenience…"
|
||||||
|
[(ngModel)]="vkycMessage"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hv-footer">
|
||||||
|
<button class="km-btn" (click)="closeVkycDialog()">Cancel</button>
|
||||||
|
<button
|
||||||
|
class="km-btn km-btn-t"
|
||||||
|
[disabled]="!vkycOfficer || !vkycExpiry || vkycSelectedChannels.length === 0"
|
||||||
|
(click)="saveVkyc()"
|
||||||
|
>
|
||||||
|
Send Link
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<!-- TOAST -->
|
<!-- TOAST -->
|
||||||
<div class="km-toast" [class.show]="toastVisible">{{ toastMsg }}</div>
|
<div class="km-toast" [class.show]="toastVisible">{{ toastMsg }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -34,7 +34,11 @@
|
|||||||
--km-g900: #0f172a;
|
--km-g900: #0f172a;
|
||||||
|
|
||||||
display: block;
|
display: block;
|
||||||
font-family: 'DM Sans', system-ui, -apple-system, sans-serif;
|
font-family:
|
||||||
|
'DM Sans',
|
||||||
|
system-ui,
|
||||||
|
-apple-system,
|
||||||
|
sans-serif;
|
||||||
background: var(--km-g50);
|
background: var(--km-g50);
|
||||||
color: var(--km-g800);
|
color: var(--km-g800);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@@ -130,7 +134,7 @@
|
|||||||
background: #fff;
|
background: #fff;
|
||||||
border: 1px solid var(--km-g200);
|
border: 1px solid var(--km-g200);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
box-shadow: 0 1px 3px rgb(0 0 0 / 8%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-ch {
|
.km-ch {
|
||||||
@@ -172,11 +176,30 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-ci-t { background: var(--km-teal-l); color: var(--km-teal); }
|
.km-ci-t {
|
||||||
.km-ci-a { background: var(--km-amber-l); color: var(--km-amber); }
|
background: var(--km-teal-l);
|
||||||
.km-ci-r { background: var(--km-red-l); color: var(--km-red); }
|
color: var(--km-teal);
|
||||||
.km-ci-b { background: var(--km-blue-l); color: var(--km-blue); }
|
}
|
||||||
.km-ci-g { background: var(--km-green-l); color: var(--km-green); }
|
|
||||||
|
.km-ci-a {
|
||||||
|
background: var(--km-amber-l);
|
||||||
|
color: var(--km-amber);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-ci-r {
|
||||||
|
background: var(--km-red-l);
|
||||||
|
color: var(--km-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-ci-b {
|
||||||
|
background: var(--km-blue-l);
|
||||||
|
color: var(--km-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-ci-g {
|
||||||
|
background: var(--km-green-l);
|
||||||
|
color: var(--km-green);
|
||||||
|
}
|
||||||
|
|
||||||
/* Badges */
|
/* Badges */
|
||||||
.km-b {
|
.km-b {
|
||||||
@@ -189,17 +212,53 @@
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-b-gr { background: var(--km-green-l); color: var(--km-green); }
|
.km-b-gr {
|
||||||
.km-b-am { background: var(--km-amber-l); color: var(--km-amber); }
|
background: var(--km-green-l);
|
||||||
.km-b-re { background: var(--km-red-l); color: var(--km-red); }
|
color: var(--km-green);
|
||||||
.km-b-or { background: var(--km-orange-l); color: var(--km-orange); }
|
}
|
||||||
.km-b-bl { background: var(--km-blue-l); color: var(--km-blue); }
|
|
||||||
.km-b-te { background: var(--km-teal-l); color: var(--km-teal); }
|
|
||||||
.km-b-gy { background: var(--km-g100); color: var(--km-g600); }
|
|
||||||
.km-b-nv { background: #e8edf5; color: var(--km-navy); }
|
|
||||||
|
|
||||||
.km-ml-auto { margin-left: auto; }
|
.km-b-am {
|
||||||
.km-ml-12 { margin-left: 12px; }
|
background: var(--km-amber-l);
|
||||||
|
color: var(--km-amber);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-b-re {
|
||||||
|
background: var(--km-red-l);
|
||||||
|
color: var(--km-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-b-or {
|
||||||
|
background: var(--km-orange-l);
|
||||||
|
color: var(--km-orange);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-b-bl {
|
||||||
|
background: var(--km-blue-l);
|
||||||
|
color: var(--km-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-b-te {
|
||||||
|
background: var(--km-teal-l);
|
||||||
|
color: var(--km-teal);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-b-gy {
|
||||||
|
background: var(--km-g100);
|
||||||
|
color: var(--km-g600);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-b-nv {
|
||||||
|
background: #e8edf5;
|
||||||
|
color: var(--km-navy);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-ml-auto {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-ml-12 {
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Buttons */
|
/* Buttons */
|
||||||
.km-btn {
|
.km-btn {
|
||||||
@@ -216,14 +275,57 @@
|
|||||||
transition: all 0.15s;
|
transition: all 0.15s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-btn-t { background: var(--km-teal); border-color: var(--km-teal); color: #fff; &:hover { opacity: 0.9; } }
|
.km-btn-t {
|
||||||
.km-btn-ot { background: #fff; border-color: var(--km-teal); color: var(--km-teal); &:hover { background: var(--km-teal-l); } }
|
background: var(--km-teal);
|
||||||
.km-btn-n { background: var(--km-navy); border-color: var(--km-navy); color: #fff; }
|
border-color: var(--km-teal);
|
||||||
.km-btn-a { background: var(--km-amber); border-color: var(--km-amber); color: #fff; }
|
color: #fff;
|
||||||
.km-btn-r { background: var(--km-red); border-color: var(--km-red); color: #fff; }
|
|
||||||
.km-btn-g { background: #fff; border-color: var(--km-g300); color: var(--km-g600); &:hover { background: var(--km-g50); } }
|
|
||||||
|
|
||||||
.km-w { width: 100%; }
|
&:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-btn-ot {
|
||||||
|
background: #fff;
|
||||||
|
border-color: var(--km-teal);
|
||||||
|
color: var(--km-teal);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--km-teal-l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-btn-n {
|
||||||
|
background: var(--km-navy);
|
||||||
|
border-color: var(--km-navy);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-btn-a {
|
||||||
|
background: var(--km-amber);
|
||||||
|
border-color: var(--km-amber);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-btn-r {
|
||||||
|
background: var(--km-red);
|
||||||
|
border-color: var(--km-red);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-btn-g {
|
||||||
|
background: #fff;
|
||||||
|
border-color: var(--km-g300);
|
||||||
|
color: var(--km-g600);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--km-g50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-w {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
/* Stat row */
|
/* Stat row */
|
||||||
.km-stat-row {
|
.km-stat-row {
|
||||||
@@ -238,12 +340,12 @@
|
|||||||
border: 1px solid var(--km-g200);
|
border: 1px solid var(--km-g200);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
box-shadow: 0 1px 3px rgb(0 0 0 / 8%);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.15s;
|
transition: all 0.15s;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 12px rgb(0 0 0 / 10%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,11 +472,30 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-sp-ac { background: var(--km-green-l); color: var(--km-green); }
|
.km-sp-ac {
|
||||||
.km-sp-fr { background: var(--km-amber-l); color: var(--km-amber); }
|
background: var(--km-green-l);
|
||||||
.km-sp-in { background: var(--km-orange-l); color: var(--km-orange); }
|
color: var(--km-green);
|
||||||
.km-sp-do { background: var(--km-red-l); color: var(--km-red); }
|
}
|
||||||
.km-sp-al { background: #fef9c3; color: #92400e; }
|
|
||||||
|
.km-sp-fr {
|
||||||
|
background: var(--km-amber-l);
|
||||||
|
color: var(--km-amber);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-sp-in {
|
||||||
|
background: var(--km-orange-l);
|
||||||
|
color: var(--km-orange);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-sp-do {
|
||||||
|
background: var(--km-red-l);
|
||||||
|
color: var(--km-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-sp-al {
|
||||||
|
background: #fef9c3;
|
||||||
|
color: #92400e;
|
||||||
|
}
|
||||||
|
|
||||||
/* Progress bar */
|
/* Progress bar */
|
||||||
.km-pbar {
|
.km-pbar {
|
||||||
@@ -424,10 +545,25 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-d-ok { background: var(--km-green-l); color: var(--km-green); }
|
.km-d-ok {
|
||||||
.km-d-pe { background: var(--km-amber-l); color: var(--km-amber); }
|
background: var(--km-green-l);
|
||||||
.km-d-fa { background: var(--km-red-l); color: var(--km-red); }
|
color: var(--km-green);
|
||||||
.km-d-tr { background: var(--km-blue-l); color: var(--km-blue); }
|
}
|
||||||
|
|
||||||
|
.km-d-pe {
|
||||||
|
background: var(--km-amber-l);
|
||||||
|
color: var(--km-amber);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-d-fa {
|
||||||
|
background: var(--km-red-l);
|
||||||
|
color: var(--km-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-d-tr {
|
||||||
|
background: var(--km-blue-l);
|
||||||
|
color: var(--km-blue);
|
||||||
|
}
|
||||||
|
|
||||||
/* Pagination */
|
/* Pagination */
|
||||||
.km-pagination {
|
.km-pagination {
|
||||||
@@ -489,12 +625,41 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-nd1 { background: var(--km-blue-l); border-color: #93c5fd; color: var(--km-blue); }
|
.km-nd1 {
|
||||||
.km-nd2 { background: var(--km-amber-l); border-color: #fcd34d; color: var(--km-amber); }
|
background: var(--km-blue-l);
|
||||||
.km-nd3 { background: var(--km-orange-l); border-color: #fdba74; color: var(--km-orange); }
|
border-color: #93c5fd;
|
||||||
.km-ndf { background: var(--km-red-l); border-color: #fca5a5; color: var(--km-red); }
|
color: var(--km-blue);
|
||||||
.km-ndi { background: #fee2e2; border-color: #f87171; color: #991b1b; }
|
}
|
||||||
.km-ndd { background: var(--km-g100); border-color: var(--km-g300); color: var(--km-g500); }
|
|
||||||
|
.km-nd2 {
|
||||||
|
background: var(--km-amber-l);
|
||||||
|
border-color: #fcd34d;
|
||||||
|
color: var(--km-amber);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-nd3 {
|
||||||
|
background: var(--km-orange-l);
|
||||||
|
border-color: #fdba74;
|
||||||
|
color: var(--km-orange);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-ndf {
|
||||||
|
background: var(--km-red-l);
|
||||||
|
border-color: #fca5a5;
|
||||||
|
color: var(--km-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-ndi {
|
||||||
|
background: #fee2e2;
|
||||||
|
border-color: #f87171;
|
||||||
|
color: #991b1b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-ndd {
|
||||||
|
background: var(--km-g100);
|
||||||
|
border-color: var(--km-g300);
|
||||||
|
color: var(--km-g500);
|
||||||
|
}
|
||||||
|
|
||||||
.km-nl {
|
.km-nl {
|
||||||
width: 1px;
|
width: 1px;
|
||||||
@@ -509,9 +674,13 @@
|
|||||||
color: var(--km-g800);
|
color: var(--km-g800);
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-warn { color: var(--km-amber); }
|
.km-warn {
|
||||||
.km-warn-o { color: var(--km-orange); }
|
color: var(--km-amber);
|
||||||
.km-warn-d { color: var(--km-g600); }
|
}
|
||||||
|
|
||||||
|
.km-warn-o {
|
||||||
|
color: var(--km-orange);
|
||||||
|
}
|
||||||
|
|
||||||
.km-ns {
|
.km-ns {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
@@ -520,9 +689,20 @@
|
|||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-ok { color: var(--km-green); font-weight: 600; }
|
.km-ok {
|
||||||
.km-pending { color: var(--km-amber); font-weight: 600; }
|
color: var(--km-green);
|
||||||
.km-fail { color: var(--km-red); font-weight: 600; }
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-pending {
|
||||||
|
color: var(--km-amber);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-fail {
|
||||||
|
color: var(--km-red);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
.km-ntags {
|
.km-ntags {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -541,12 +721,41 @@
|
|||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-cp-sms { background: #eff6ff; color: #1d4ed8; border-color: #93c5fd; }
|
.km-cp-sms {
|
||||||
.km-cp-mail { background: #f0fdf4; color: #15803d; border-color: #86efac; }
|
background: #eff6ff;
|
||||||
.km-cp-ivr { background: #faf5ff; color: #7c3aed; border-color: #c4b5fd; }
|
color: #1d4ed8;
|
||||||
.km-cp-post { background: #fff7ed; color: #c2410c; border-color: #fdba74; }
|
border-color: #93c5fd;
|
||||||
.km-cp-vis { background: var(--km-teal-l); color: var(--km-teal); border-color: #5eead4; }
|
}
|
||||||
.km-cp-vid { background: #ede9fe; color: #5b21b6; border-color: #a78bfa; }
|
|
||||||
|
.km-cp-mail {
|
||||||
|
background: #f0fdf4;
|
||||||
|
color: #15803d;
|
||||||
|
border-color: #86efac;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-cp-ivr {
|
||||||
|
background: #faf5ff;
|
||||||
|
color: #7c3aed;
|
||||||
|
border-color: #c4b5fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-cp-post {
|
||||||
|
background: #fff7ed;
|
||||||
|
color: #c2410c;
|
||||||
|
border-color: #fdba74;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-cp-vis {
|
||||||
|
background: var(--km-teal-l);
|
||||||
|
color: var(--km-teal);
|
||||||
|
border-color: #5eead4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-cp-vid {
|
||||||
|
background: #ede9fe;
|
||||||
|
color: #5b21b6;
|
||||||
|
border-color: #a78bfa;
|
||||||
|
}
|
||||||
|
|
||||||
.km-row-actions {
|
.km-row-actions {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
@@ -574,9 +783,20 @@
|
|||||||
background: var(--km-teal-l);
|
background: var(--km-teal-l);
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-channel-i { font-size: 16px; margin-bottom: 3px; }
|
.km-channel-i {
|
||||||
.km-channel-n { font-size: 11px; font-weight: 600; }
|
font-size: 16px;
|
||||||
.km-channel-d { font-size: 10px; color: var(--km-g500); }
|
margin-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-channel-n {
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-channel-d {
|
||||||
|
font-size: 10px;
|
||||||
|
color: var(--km-g500);
|
||||||
|
}
|
||||||
|
|
||||||
/* Meta items */
|
/* Meta items */
|
||||||
.km-mi {
|
.km-mi {
|
||||||
@@ -618,15 +838,79 @@
|
|||||||
transition: all 0.15s;
|
transition: all 0.15s;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 12px rgb(0 0 0 / 10%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-sc-ac { border-color: #86efac; background: var(--km-green-l); .km-sc-l, .km-sc-d { color: #166534; } .km-sc-n { color: var(--km-green); } }
|
.km-sc-ac {
|
||||||
.km-sc-fr { border-color: #fcd34d; background: var(--km-amber-l); .km-sc-l, .km-sc-d { color: #92400e; } .km-sc-n { color: var(--km-amber); } }
|
border-color: #86efac;
|
||||||
.km-sc-in { border-color: #fdba74; background: var(--km-orange-l); .km-sc-l, .km-sc-d { color: #7c2d12; } .km-sc-n { color: var(--km-orange); } }
|
background: var(--km-green-l);
|
||||||
.km-sc-do { border-color: #fca5a5; background: var(--km-red-l); .km-sc-l, .km-sc-d { color: #7f1d1d; } .km-sc-n { color: var(--km-red); } }
|
|
||||||
.km-sc-al { border-color: #fde047; background: #fef9c3; .km-sc-l, .km-sc-d { color: #713f12; } .km-sc-n { color: #92400e; } }
|
.km-sc-l,
|
||||||
|
.km-sc-d {
|
||||||
|
color: #166534;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-sc-n {
|
||||||
|
color: var(--km-green);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-sc-fr {
|
||||||
|
border-color: #fcd34d;
|
||||||
|
background: var(--km-amber-l);
|
||||||
|
|
||||||
|
.km-sc-l,
|
||||||
|
.km-sc-d {
|
||||||
|
color: #92400e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-sc-n {
|
||||||
|
color: var(--km-amber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-sc-in {
|
||||||
|
border-color: #fdba74;
|
||||||
|
background: var(--km-orange-l);
|
||||||
|
|
||||||
|
.km-sc-l,
|
||||||
|
.km-sc-d {
|
||||||
|
color: #7c2d12;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-sc-n {
|
||||||
|
color: var(--km-orange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-sc-do {
|
||||||
|
border-color: #fca5a5;
|
||||||
|
background: var(--km-red-l);
|
||||||
|
|
||||||
|
.km-sc-l,
|
||||||
|
.km-sc-d {
|
||||||
|
color: #7f1d1d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-sc-n {
|
||||||
|
color: var(--km-red);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-sc-al {
|
||||||
|
border-color: #fde047;
|
||||||
|
background: #fef9c3;
|
||||||
|
|
||||||
|
.km-sc-l,
|
||||||
|
.km-sc-d {
|
||||||
|
color: #713f12;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-sc-n {
|
||||||
|
color: #92400e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.km-sc-l {
|
.km-sc-l {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
@@ -719,7 +1003,7 @@
|
|||||||
.km-overlay {
|
.km-overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
background: rgba(0, 0, 0, 0.45);
|
background: rgb(0 0 0 / 45%);
|
||||||
z-index: 1200;
|
z-index: 1200;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -735,7 +1019,7 @@
|
|||||||
max-height: 90vh;
|
max-height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 20px 60px rgb(0 0 0 / 20%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-mh {
|
.km-mh {
|
||||||
@@ -787,7 +1071,9 @@
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
&:hover { background: var(--km-g100); }
|
&:hover {
|
||||||
|
background: var(--km-g100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-mbody {
|
.km-mbody {
|
||||||
@@ -863,7 +1149,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-ps-done::after { background: var(--km-teal); }
|
.km-ps-done::after {
|
||||||
|
background: var(--km-teal);
|
||||||
|
}
|
||||||
|
|
||||||
.km-ps-dot {
|
.km-ps-dot {
|
||||||
width: 28px;
|
width: 28px;
|
||||||
@@ -881,9 +1169,23 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-ps-done .km-ps-dot { background: var(--km-teal); border-color: var(--km-teal); color: #fff; }
|
.km-ps-done .km-ps-dot {
|
||||||
.km-ps-current .km-ps-dot { background: #fff; border-color: var(--km-amber); color: var(--km-amber); }
|
background: var(--km-teal);
|
||||||
.km-ps-danger .km-ps-dot { background: #fff; border-color: var(--km-red); color: var(--km-red); }
|
border-color: var(--km-teal);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-ps-current .km-ps-dot {
|
||||||
|
background: #fff;
|
||||||
|
border-color: var(--km-amber);
|
||||||
|
color: var(--km-amber);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-ps-danger .km-ps-dot {
|
||||||
|
background: #fff;
|
||||||
|
border-color: var(--km-red);
|
||||||
|
color: var(--km-red);
|
||||||
|
}
|
||||||
|
|
||||||
.km-ps-label {
|
.km-ps-label {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
@@ -893,9 +1195,19 @@
|
|||||||
max-width: 70px;
|
max-width: 70px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-ps-done .km-ps-label { color: var(--km-teal); }
|
.km-ps-done .km-ps-label {
|
||||||
.km-ps-current .km-ps-label { color: var(--km-amber); font-weight: 600; }
|
color: var(--km-teal);
|
||||||
.km-ps-danger .km-ps-label { color: var(--km-red); font-weight: 600; }
|
}
|
||||||
|
|
||||||
|
.km-ps-current .km-ps-label {
|
||||||
|
color: var(--km-amber);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-ps-danger .km-ps-label {
|
||||||
|
color: var(--km-red);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
/* Next action banner */
|
/* Next action banner */
|
||||||
.km-next-banner {
|
.km-next-banner {
|
||||||
@@ -908,15 +1220,45 @@
|
|||||||
gap: 12px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-nb-alert { background: var(--km-amber-l); border-color: #fcd34d; }
|
.km-nb-alert {
|
||||||
.km-nb-urgent { background: var(--km-orange-l); border-color: #fdba74; }
|
background: var(--km-amber-l);
|
||||||
.km-nb-freeze { background: var(--km-amber-l); border-color: #fcd34d; }
|
border-color: #fcd34d;
|
||||||
.km-nb-inop { background: var(--km-orange-l); border-color: #fdba74; }
|
}
|
||||||
.km-nb-dormant { background: var(--km-red-l); border-color: #fca5a5; }
|
|
||||||
|
|
||||||
.km-nb-icon { font-size: 22px; flex-shrink: 0; }
|
.km-nb-urgent {
|
||||||
.km-nb-title { font-size: 13px; font-weight: 700; margin-bottom: 2px; }
|
background: var(--km-orange-l);
|
||||||
.km-nb-sub { font-size: 12px; }
|
border-color: #fdba74;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-nb-freeze {
|
||||||
|
background: var(--km-amber-l);
|
||||||
|
border-color: #fcd34d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-nb-inop {
|
||||||
|
background: var(--km-orange-l);
|
||||||
|
border-color: #fdba74;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-nb-dormant {
|
||||||
|
background: var(--km-red-l);
|
||||||
|
border-color: #fca5a5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-nb-icon {
|
||||||
|
font-size: 22px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-nb-title {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-nb-sub {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Modal stat strip */
|
/* Modal stat strip */
|
||||||
.km-mstat-row {
|
.km-mstat-row {
|
||||||
@@ -969,7 +1311,9 @@
|
|||||||
padding: 12px 0;
|
padding: 12px 0;
|
||||||
border-bottom: 1px solid var(--km-g100);
|
border-bottom: 1px solid var(--km-g100);
|
||||||
|
|
||||||
&:last-child { border-bottom: none; }
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-mti-dot {
|
.km-mti-dot {
|
||||||
@@ -985,14 +1329,36 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-mti-done { background: var(--km-green-l); border-color: var(--km-green); color: var(--km-green); }
|
.km-mti-done {
|
||||||
.km-mti-pend { background: var(--km-amber-l); border-color: var(--km-amber); color: var(--km-amber); }
|
background: var(--km-green-l);
|
||||||
|
border-color: var(--km-green);
|
||||||
|
color: var(--km-green);
|
||||||
|
}
|
||||||
|
|
||||||
.km-mti-text { font-size: 13px; font-weight: 500; }
|
.km-mti-pend {
|
||||||
.km-done { color: var(--km-g700); }
|
background: var(--km-amber-l);
|
||||||
.km-pend { color: var(--km-amber); }
|
border-color: var(--km-amber);
|
||||||
|
color: var(--km-amber);
|
||||||
|
}
|
||||||
|
|
||||||
.km-mti-sub { font-size: 11px; color: var(--km-g400); margin-top: 2px; }
|
.km-mti-text {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-done {
|
||||||
|
color: var(--km-g700);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-pend {
|
||||||
|
color: var(--km-amber);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-mti-sub {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--km-g400);
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
.km-pending-row {
|
.km-pending-row {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -1009,8 +1375,15 @@
|
|||||||
color: var(--km-g400);
|
color: var(--km-g400);
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-empty-i { font-size: 28px; margin-bottom: 8px; }
|
.km-empty-i {
|
||||||
.km-empty-s { font-size: 12px; margin-top: 4px; }
|
font-size: 28px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-empty-s {
|
||||||
|
font-size: 12px;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Evidence */
|
/* Evidence */
|
||||||
.km-map {
|
.km-map {
|
||||||
@@ -1069,8 +1442,15 @@
|
|||||||
gap: 12px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.km-action-t { font-size: 13px; font-weight: 600; }
|
.km-action-t {
|
||||||
.km-action-d { font-size: 12px; color: var(--km-g500); }
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-action-d {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--km-g500);
|
||||||
|
}
|
||||||
|
|
||||||
/* Toast */
|
/* Toast */
|
||||||
.km-toast {
|
.km-toast {
|
||||||
@@ -1094,12 +1474,178 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 900px) {
|
@media (width <= 900px) {
|
||||||
.km-stat-row,
|
.km-stat-row,
|
||||||
.km-sc-row { grid-template-columns: repeat(2, 1fr); }
|
.km-sc-row {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
.km-r2,
|
.km-r2,
|
||||||
.km-notif-grid { grid-template-columns: 1fr; }
|
.km-notif-grid {
|
||||||
.km-mstat-row { grid-template-columns: repeat(2, 1fr); }
|
grid-template-columns: 1fr;
|
||||||
.km-prog-steps { flex-wrap: wrap; gap: 10px; }
|
}
|
||||||
.km-ps::after { display: none; }
|
|
||||||
|
.km-mstat-row {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-prog-steps {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-ps::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Home Visit Schedule Dialog */
|
||||||
|
.hv-modal {
|
||||||
|
width: 520px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hv-body {
|
||||||
|
padding: 18px 22px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 14px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hv-addr {
|
||||||
|
background: #f8fafc;
|
||||||
|
border: 1px solid var(--km-g200);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 12px 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hv-addr-label {
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
color: #64748b;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hv-addr-name {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #0f172a;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hv-addr-text {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #334155;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hv-addr-branch {
|
||||||
|
margin-top: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hv-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hv-label {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #334155;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hv-req {
|
||||||
|
color: #dc2626;
|
||||||
|
margin-left: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hv-input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 9px 12px;
|
||||||
|
border: 1px solid var(--km-g200);
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #0f172a;
|
||||||
|
background: #fff;
|
||||||
|
font-family: inherit;
|
||||||
|
transition:
|
||||||
|
border-color 0.15s,
|
||||||
|
box-shadow 0.15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hv-input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--km-teal);
|
||||||
|
box-shadow: 0 0 0 3px rgb(20 184 166 / 15%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hv-textarea {
|
||||||
|
resize: vertical;
|
||||||
|
min-height: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hv-footer {
|
||||||
|
padding: 14px 22px;
|
||||||
|
border-top: 1px solid var(--km-g200);
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 10px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.km-btn:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Video KYC Dialog */
|
||||||
|
.vkyc-ic {
|
||||||
|
color: var(--km-teal);
|
||||||
|
margin-right: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vkyc-chans {
|
||||||
|
display: flex;
|
||||||
|
gap: 18px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vkyc-chan {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #334155;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vkyc-chan input {
|
||||||
|
accent-color: var(--km-teal);
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vkyc-hint {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #64748b;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vkyc-link {
|
||||||
|
background: #f1f5f9;
|
||||||
|
border: 1px dashed #cbd5e1;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 9px 12px;
|
||||||
|
font-family: 'Roboto Mono', 'DM Mono', monospace;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #0f172a;
|
||||||
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,6 +89,38 @@ export class KycManagementComponent {
|
|||||||
toastVisible = false;
|
toastVisible = false;
|
||||||
private toastTimer: any;
|
private toastTimer: any;
|
||||||
|
|
||||||
|
/** Home Visit scheduling dialog */
|
||||||
|
homeVisitOpen = false;
|
||||||
|
homeVisitOfficer = '';
|
||||||
|
homeVisitDateTime = '';
|
||||||
|
homeVisitNote = '';
|
||||||
|
bankOfficers = [
|
||||||
|
'Amit Sharma — Branch Officer (Bhopal Main)',
|
||||||
|
'Neha Verma — KYC Officer (Bhopal Main)',
|
||||||
|
'Ravi Kulkarni — Field Officer (Bhopal Zone-2)',
|
||||||
|
'Sunita Patel — Compliance Officer (Bhopal Main)',
|
||||||
|
'Manoj Tiwari — Field Officer (Indore Zone-1)'
|
||||||
|
];
|
||||||
|
scheduledHomeVisits: { client: string; address: string; officer: string; dateTime: string; note: string }[] = [];
|
||||||
|
|
||||||
|
/** Video KYC link dialog */
|
||||||
|
vkycOpen = false;
|
||||||
|
vkycOfficer = '';
|
||||||
|
vkycExpiry = '';
|
||||||
|
vkycChannels = { sms: true, email: true, whatsapp: false };
|
||||||
|
vkycMessage = '';
|
||||||
|
vkycSessionId = '';
|
||||||
|
sentVkycLinks: {
|
||||||
|
client: string;
|
||||||
|
mobile: string;
|
||||||
|
email: string;
|
||||||
|
officer: string;
|
||||||
|
expiry: string;
|
||||||
|
channels: string[];
|
||||||
|
sessionId: string;
|
||||||
|
link: string;
|
||||||
|
}[] = [];
|
||||||
|
|
||||||
clients: Record<string, KmClient> = {
|
clients: Record<string, KmClient> = {
|
||||||
rajesh: {
|
rajesh: {
|
||||||
id: 'rajesh',
|
id: 'rajesh',
|
||||||
@@ -119,14 +151,35 @@ export class KycManagementComponent {
|
|||||||
branch: 'Bhopal Main'
|
branch: 'Bhopal Main'
|
||||||
},
|
},
|
||||||
notices: [
|
notices: [
|
||||||
{ no: 'N1', channel: 'SMS + Email', date: '31 Mar 2027', ref: 'MSG-2027-0331-001', delivery: 'Delivered', response: 'No Action' },
|
{
|
||||||
{ no: 'N2', channel: 'Reg. Post + IVR', date: '10 Apr 2027', ref: 'RP-BPL-20270410-443', delivery: 'In Transit', response: 'Pending' }
|
no: 'N1',
|
||||||
|
channel: 'SMS + Email',
|
||||||
|
date: '31 Mar 2027',
|
||||||
|
ref: 'MSG-2027-0331-001',
|
||||||
|
delivery: 'Delivered',
|
||||||
|
response: 'No Action'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 'N2',
|
||||||
|
channel: 'Reg. Post + IVR',
|
||||||
|
date: '10 Apr 2027',
|
||||||
|
ref: 'RP-BPL-20270410-443',
|
||||||
|
delivery: 'In Transit',
|
||||||
|
response: 'Pending'
|
||||||
|
}
|
||||||
],
|
],
|
||||||
noticesSent: 2,
|
noticesSent: 2,
|
||||||
noticePending: 'Notice 3',
|
noticePending: 'Notice 3',
|
||||||
nextStage: 'Debit Freeze',
|
nextStage: 'Debit Freeze',
|
||||||
pendingActions: ['Send Notice 3 (due 20 Apr 2027)', 'Schedule Branch Visit', 'Send Video KYC link'],
|
pendingActions: [
|
||||||
actionTaken: ['Notice 1 delivered', 'Notice 2 dispatched via Reg. Post'],
|
'Send Notice 3 (due 20 Apr 2027)',
|
||||||
|
'Schedule Home Visit',
|
||||||
|
'Send Video KYC link'
|
||||||
|
],
|
||||||
|
actionTaken: [
|
||||||
|
'Notice 1 delivered',
|
||||||
|
'Notice 2 dispatched via Reg. Post'
|
||||||
|
],
|
||||||
evidence: null
|
evidence: null
|
||||||
},
|
},
|
||||||
priya: {
|
priya: {
|
||||||
@@ -158,15 +211,45 @@ export class KycManagementComponent {
|
|||||||
branch: 'Bhopal Main'
|
branch: 'Bhopal Main'
|
||||||
},
|
},
|
||||||
notices: [
|
notices: [
|
||||||
{ no: 'N1', channel: 'SMS + Email', date: '10 Mar 2027', ref: 'MSG-2027-0310-003', delivery: 'Delivered', response: 'No Response' },
|
{
|
||||||
{ no: 'N2', channel: 'Reg. Post', date: '20 Mar 2027', ref: 'RP-BPL-20270320-091', delivery: 'Delivered', response: 'No Response' },
|
no: 'N1',
|
||||||
{ no: 'N3', channel: 'Branch Visit', date: '30 Mar 2027', ref: 'VIS-BPL-20270330-012', delivery: 'Visit Done', response: 'Refused' }
|
channel: 'SMS + Email',
|
||||||
|
date: '10 Mar 2027',
|
||||||
|
ref: 'MSG-2027-0310-003',
|
||||||
|
delivery: 'Delivered',
|
||||||
|
response: 'No Response'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 'N2',
|
||||||
|
channel: 'Reg. Post',
|
||||||
|
date: '20 Mar 2027',
|
||||||
|
ref: 'RP-BPL-20270320-091',
|
||||||
|
delivery: 'Delivered',
|
||||||
|
response: 'No Response'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 'N3',
|
||||||
|
channel: 'Home Visit',
|
||||||
|
date: '30 Mar 2027',
|
||||||
|
ref: 'VIS-BPL-20270330-012',
|
||||||
|
delivery: 'Visit Done',
|
||||||
|
response: 'Refused'
|
||||||
|
}
|
||||||
],
|
],
|
||||||
noticesSent: 3,
|
noticesSent: 3,
|
||||||
noticePending: 'None — all 3 sent',
|
noticePending: 'None — all 3 sent',
|
||||||
nextStage: 'Inoperative by 30 Jun 2027',
|
nextStage: 'Inoperative by 30 Jun 2027',
|
||||||
pendingActions: ['Account in Debit Freeze', 'Inoperative transition due 30 Jun 2027', 'Maker-checker unfreeze pending'],
|
pendingActions: [
|
||||||
actionTaken: ['Notice 1 delivered', 'Notice 2 delivered via Reg. Post', 'Notice 3 — Branch visit done, client refused', 'Debit Freeze applied 10 Apr 2027'],
|
'Account in Debit Freeze',
|
||||||
|
'Inoperative transition due 30 Jun 2027',
|
||||||
|
'Maker-checker unfreeze pending'
|
||||||
|
],
|
||||||
|
actionTaken: [
|
||||||
|
'Notice 1 delivered',
|
||||||
|
'Notice 2 delivered via Reg. Post',
|
||||||
|
'Notice 3 — Branch visit done, client refused',
|
||||||
|
'Debit Freeze applied 10 Apr 2027'
|
||||||
|
],
|
||||||
evidence: {
|
evidence: {
|
||||||
type: 'visit',
|
type: 'visit',
|
||||||
date: '30 Mar 2027',
|
date: '30 Mar 2027',
|
||||||
@@ -206,15 +289,46 @@ export class KycManagementComponent {
|
|||||||
branch: 'Bhopal South'
|
branch: 'Bhopal South'
|
||||||
},
|
},
|
||||||
notices: [
|
notices: [
|
||||||
{ no: 'N1', channel: 'SMS + Email', date: '13 Feb 2027', ref: 'MSG-2027-0213-006', delivery: 'Delivered', response: 'No Response' },
|
{
|
||||||
{ no: 'N2', channel: 'Reg. Post + IVR', date: '23 Feb 2027', ref: 'RP-BPL-20270223-044', delivery: 'Delivered', response: 'No Response' },
|
no: 'N1',
|
||||||
{ no: 'N3', channel: 'Video KYC', date: '5 Mar 2027', ref: 'VKYC-2027-0305-007', delivery: 'No Response', response: 'No Action' }
|
channel: 'SMS + Email',
|
||||||
|
date: '13 Feb 2027',
|
||||||
|
ref: 'MSG-2027-0213-006',
|
||||||
|
delivery: 'Delivered',
|
||||||
|
response: 'No Response'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 'N2',
|
||||||
|
channel: 'Reg. Post + IVR',
|
||||||
|
date: '23 Feb 2027',
|
||||||
|
ref: 'RP-BPL-20270223-044',
|
||||||
|
delivery: 'Delivered',
|
||||||
|
response: 'No Response'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 'N3',
|
||||||
|
channel: 'Video KYC',
|
||||||
|
date: '5 Mar 2027',
|
||||||
|
ref: 'VKYC-2027-0305-007',
|
||||||
|
delivery: 'No Response',
|
||||||
|
response: 'No Action'
|
||||||
|
}
|
||||||
],
|
],
|
||||||
noticesSent: 3,
|
noticesSent: 3,
|
||||||
noticePending: 'None',
|
noticePending: 'None',
|
||||||
nextStage: 'Dormant by 30 Sep 2027',
|
nextStage: 'Dormant by 30 Sep 2027',
|
||||||
pendingActions: ['Account Inoperative — all txns blocked', 'Dormant transition due 30 Sep 2027', 'RBI Dormant Account reporting'],
|
pendingActions: [
|
||||||
actionTaken: ['Notice 1 delivered', 'Notice 2 delivered via Reg. Post', 'Notice 3 — Video KYC invite sent (no response)', 'Debit Freeze 15 Mar 2027', 'Inoperative 15 May 2027'],
|
'Account Inoperative — all txns blocked',
|
||||||
|
'Dormant transition due 30 Sep 2027',
|
||||||
|
'RBI Dormant Account reporting'
|
||||||
|
],
|
||||||
|
actionTaken: [
|
||||||
|
'Notice 1 delivered',
|
||||||
|
'Notice 2 delivered via Reg. Post',
|
||||||
|
'Notice 3 — Video KYC invite sent (no response)',
|
||||||
|
'Debit Freeze 15 Mar 2027',
|
||||||
|
'Inoperative 15 May 2027'
|
||||||
|
],
|
||||||
evidence: {
|
evidence: {
|
||||||
type: 'vkyc',
|
type: 'vkyc',
|
||||||
date: '5 Mar 2027',
|
date: '5 Mar 2027',
|
||||||
@@ -252,22 +366,54 @@ export class KycManagementComponent {
|
|||||||
branch: 'Bhopal East'
|
branch: 'Bhopal East'
|
||||||
},
|
},
|
||||||
notices: [
|
notices: [
|
||||||
{ no: 'N1', channel: 'SMS + Email', date: '1 Dec 2026', ref: 'MSG-2026-1201-009', delivery: 'Delivered', response: 'No Response' },
|
{
|
||||||
{ no: 'N2', channel: 'Reg. Post', date: '11 Dec 2026', ref: 'RP-BPL-20261211-077', delivery: 'Delivered', response: 'No Response' },
|
no: 'N1',
|
||||||
{ no: 'N3', channel: 'Branch Visit', date: '22 Dec 2026', ref: 'VIS-BPL-20261222-019', delivery: 'Not Found', response: 'Not Found at Address' }
|
channel: 'SMS + Email',
|
||||||
|
date: '1 Dec 2026',
|
||||||
|
ref: 'MSG-2026-1201-009',
|
||||||
|
delivery: 'Delivered',
|
||||||
|
response: 'No Response'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 'N2',
|
||||||
|
channel: 'Reg. Post',
|
||||||
|
date: '11 Dec 2026',
|
||||||
|
ref: 'RP-BPL-20261211-077',
|
||||||
|
delivery: 'Delivered',
|
||||||
|
response: 'No Response'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 'N3',
|
||||||
|
channel: 'Home Visit',
|
||||||
|
date: '22 Dec 2026',
|
||||||
|
ref: 'VIS-BPL-20261222-019',
|
||||||
|
delivery: 'Not Found',
|
||||||
|
response: 'Not Found at Address'
|
||||||
|
}
|
||||||
],
|
],
|
||||||
noticesSent: 3,
|
noticesSent: 3,
|
||||||
noticePending: 'None',
|
noticePending: 'None',
|
||||||
nextStage: 'Dormant (Final) — RBI Reporting',
|
nextStage: 'Dormant (Final) — RBI Reporting',
|
||||||
pendingActions: ['RBI Dormant Account Report submission', 'Branch Manager approval for any reversal', 'Regional Manager sign-off required'],
|
pendingActions: [
|
||||||
actionTaken: ['Notice 1–3 sent, all no response', 'Debit Freeze 1 Jan 2027', 'Inoperative 2 Mar 2027', 'Dormant 1 Jun 2027', 'RBI report auto-generated'],
|
'RBI Dormant Account Report submission',
|
||||||
|
'Branch Manager approval for any reversal',
|
||||||
|
'Regional Manager sign-off required'
|
||||||
|
],
|
||||||
|
actionTaken: [
|
||||||
|
'Notice 1–3 sent, all no response',
|
||||||
|
'Debit Freeze 1 Jan 2027',
|
||||||
|
'Inoperative 2 Mar 2027',
|
||||||
|
'Dormant 1 Jun 2027',
|
||||||
|
'RBI report auto-generated'
|
||||||
|
],
|
||||||
evidence: {
|
evidence: {
|
||||||
type: 'visit',
|
type: 'visit',
|
||||||
date: '22 Dec 2026',
|
date: '22 Dec 2026',
|
||||||
officer: 'Rekha Sharma',
|
officer: 'Rekha Sharma',
|
||||||
gps: '23.2491° N, 77.4384° E',
|
gps: '23.2491° N, 77.4384° E',
|
||||||
location: 'Awadhpuri, Bhopal',
|
location: 'Awadhpuri, Bhopal',
|
||||||
outcome: 'Client not found at registered address. Neighbours confirmed relocation. Address verification required.',
|
outcome:
|
||||||
|
'Client not found at registered address. Neighbours confirmed relocation. Address verification required.',
|
||||||
docket: 'VIS-BPL-20261222-019'
|
docket: 'VIS-BPL-20261222-019'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -300,12 +446,23 @@ export class KycManagementComponent {
|
|||||||
branch: 'Bhopal Main'
|
branch: 'Bhopal Main'
|
||||||
},
|
},
|
||||||
notices: [
|
notices: [
|
||||||
{ no: 'N1', channel: 'SMS + Email', date: '5 Apr 2027', ref: 'MSG-2027-0405-011', delivery: 'Delivered', response: 'No Action' }
|
{
|
||||||
|
no: 'N1',
|
||||||
|
channel: 'SMS + Email',
|
||||||
|
date: '5 Apr 2027',
|
||||||
|
ref: 'MSG-2027-0405-011',
|
||||||
|
delivery: 'Delivered',
|
||||||
|
response: 'No Action'
|
||||||
|
}
|
||||||
],
|
],
|
||||||
noticesSent: 1,
|
noticesSent: 1,
|
||||||
noticePending: 'Notice 2 & 3',
|
noticePending: 'Notice 2 & 3',
|
||||||
nextStage: 'Debit Freeze if no action',
|
nextStage: 'Debit Freeze if no action',
|
||||||
pendingActions: ['Send Notice 2 (due 15 Apr 2027)', 'Send Notice 3 (due 25 Apr 2027)', 'Branch visit if needed'],
|
pendingActions: [
|
||||||
|
'Send Notice 2 (due 15 Apr 2027)',
|
||||||
|
'Send Notice 3 (due 25 Apr 2027)',
|
||||||
|
'Branch visit if needed'
|
||||||
|
],
|
||||||
actionTaken: ['Notice 1 delivered 5 Apr 2027'],
|
actionTaken: ['Notice 1 delivered 5 Apr 2027'],
|
||||||
evidence: null
|
evidence: null
|
||||||
},
|
},
|
||||||
@@ -338,14 +495,35 @@ export class KycManagementComponent {
|
|||||||
branch: 'Bhopal North'
|
branch: 'Bhopal North'
|
||||||
},
|
},
|
||||||
notices: [
|
notices: [
|
||||||
{ no: 'N1', channel: 'SMS + Email', date: '29 Mar 2027', ref: 'MSG-2027-0329-014', delivery: 'Delivered', response: 'No Action' },
|
{
|
||||||
{ no: 'N2', channel: 'Reg. Post + IVR', date: '8 Apr 2027', ref: 'RP-BPL-20270408-088', delivery: 'Delivered', response: 'No Response' }
|
no: 'N1',
|
||||||
|
channel: 'SMS + Email',
|
||||||
|
date: '29 Mar 2027',
|
||||||
|
ref: 'MSG-2027-0329-014',
|
||||||
|
delivery: 'Delivered',
|
||||||
|
response: 'No Action'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 'N2',
|
||||||
|
channel: 'Reg. Post + IVR',
|
||||||
|
date: '8 Apr 2027',
|
||||||
|
ref: 'RP-BPL-20270408-088',
|
||||||
|
delivery: 'Delivered',
|
||||||
|
response: 'No Response'
|
||||||
|
}
|
||||||
],
|
],
|
||||||
noticesSent: 2,
|
noticesSent: 2,
|
||||||
noticePending: 'URGENT: Notice 3',
|
noticePending: 'URGENT: Notice 3',
|
||||||
nextStage: 'Debit Freeze in 3 days',
|
nextStage: 'Debit Freeze in 3 days',
|
||||||
pendingActions: ['URGENT: Send Notice 3 NOW', 'Schedule Branch Visit immediately', 'Consider Video KYC as last resort'],
|
pendingActions: [
|
||||||
actionTaken: ['Notice 1 delivered', 'Notice 2 delivered via Reg. Post + IVR'],
|
'URGENT: Send Notice 3 NOW',
|
||||||
|
'Schedule Home Visit immediately',
|
||||||
|
'Consider Video KYC as last resort'
|
||||||
|
],
|
||||||
|
actionTaken: [
|
||||||
|
'Notice 1 delivered',
|
||||||
|
'Notice 2 delivered via Reg. Post + IVR'
|
||||||
|
],
|
||||||
evidence: null
|
evidence: null
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -384,6 +562,108 @@ export class KycManagementComponent {
|
|||||||
this.toastTimer = setTimeout(() => (this.toastVisible = false), 2800);
|
this.toastTimer = setTimeout(() => (this.toastVisible = false), 2800);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Routes a "Take Action" click. Opens the Home Visit dialog if the action is
|
||||||
|
* a home-visit scheduling action; otherwise falls back to a toast confirmation.
|
||||||
|
*/
|
||||||
|
takeAction(action: string): void {
|
||||||
|
if (!this.current) return;
|
||||||
|
const lower = action.toLowerCase();
|
||||||
|
if (lower.includes('home visit')) {
|
||||||
|
this.openHomeVisitDialog();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (lower.includes('video kyc')) {
|
||||||
|
this.openVkycDialog();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.toast(action + ' initiated for ' + this.current.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
openHomeVisitDialog(): void {
|
||||||
|
this.homeVisitOfficer = '';
|
||||||
|
this.homeVisitNote = '';
|
||||||
|
// Default to tomorrow at 10:00 AM (datetime-local format: YYYY-MM-DDTHH:mm)
|
||||||
|
const t = new Date();
|
||||||
|
t.setDate(t.getDate() + 1);
|
||||||
|
t.setHours(10, 0, 0, 0);
|
||||||
|
const pad = (n: number) => n.toString().padStart(2, '0');
|
||||||
|
this.homeVisitDateTime = `${t.getFullYear()}-${pad(t.getMonth() + 1)}-${pad(t.getDate())}T${pad(t.getHours())}:${pad(t.getMinutes())}`;
|
||||||
|
this.homeVisitOpen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
closeHomeVisitDialog(): void {
|
||||||
|
this.homeVisitOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveHomeVisit(): void {
|
||||||
|
if (!this.current || !this.homeVisitOfficer || !this.homeVisitDateTime) return;
|
||||||
|
this.scheduledHomeVisits.push({
|
||||||
|
client: this.current.name,
|
||||||
|
address: this.current.contact.address,
|
||||||
|
officer: this.homeVisitOfficer,
|
||||||
|
dateTime: this.homeVisitDateTime,
|
||||||
|
note: this.homeVisitNote
|
||||||
|
});
|
||||||
|
const when = new Date(this.homeVisitDateTime).toLocaleString('en-IN', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: 'short',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit'
|
||||||
|
});
|
||||||
|
this.toast(`Home Visit scheduled for ${this.current.name} on ${when}`);
|
||||||
|
this.homeVisitOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
openVkycDialog(): void {
|
||||||
|
this.vkycOfficer = '';
|
||||||
|
this.vkycMessage = '';
|
||||||
|
this.vkycChannels = { sms: true, email: true, whatsapp: false };
|
||||||
|
// Default: link expires 48 hours from now (RBI Video-based KYC norms)
|
||||||
|
const t = new Date();
|
||||||
|
t.setHours(t.getHours() + 48);
|
||||||
|
const pad = (n: number) => n.toString().padStart(2, '0');
|
||||||
|
this.vkycExpiry = `${t.getFullYear()}-${pad(t.getMonth() + 1)}-${pad(t.getDate())}T${pad(t.getHours())}:${pad(t.getMinutes())}`;
|
||||||
|
// Generate a session id (token preview only — server would issue the real one)
|
||||||
|
this.vkycSessionId = 'VKYC-' + Math.random().toString(36).slice(2, 10).toUpperCase();
|
||||||
|
this.vkycOpen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
closeVkycDialog(): void {
|
||||||
|
this.vkycOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get vkycSelectedChannels(): string[] {
|
||||||
|
const out: string[] = [];
|
||||||
|
if (this.vkycChannels.sms) out.push('SMS');
|
||||||
|
if (this.vkycChannels.email) out.push('Email');
|
||||||
|
if (this.vkycChannels.whatsapp) out.push('WhatsApp');
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
get vkycLink(): string {
|
||||||
|
return `https://vkyc.bank.example/session/${this.vkycSessionId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveVkyc(): void {
|
||||||
|
if (!this.current || !this.vkycOfficer || !this.vkycExpiry) return;
|
||||||
|
const channels = this.vkycSelectedChannels;
|
||||||
|
if (channels.length === 0) return;
|
||||||
|
this.sentVkycLinks.push({
|
||||||
|
client: this.current.name,
|
||||||
|
mobile: this.current.contact.mobile,
|
||||||
|
email: this.current.contact.email,
|
||||||
|
officer: this.vkycOfficer,
|
||||||
|
expiry: this.vkycExpiry,
|
||||||
|
channels,
|
||||||
|
sessionId: this.vkycSessionId,
|
||||||
|
link: this.vkycLink
|
||||||
|
});
|
||||||
|
this.toast(`Video KYC link sent to ${this.current.name} via ${channels.join(' + ')}`);
|
||||||
|
this.vkycOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Compliance journey stepper state for a given client */
|
/** Compliance journey stepper state for a given client */
|
||||||
getStepperState(c: KmClient): { label: string; state: 'done' | 'pending' | 'current' | 'danger' }[] {
|
getStepperState(c: KmClient): { label: string; state: 'done' | 'pending' | 'current' | 'danger' }[] {
|
||||||
return [
|
return [
|
||||||
@@ -393,19 +673,20 @@ export class KycManagementComponent {
|
|||||||
{
|
{
|
||||||
label: 'Notice 3',
|
label: 'Notice 3',
|
||||||
state:
|
state:
|
||||||
c.noticesSent >= 3
|
c.noticesSent >= 3 ? 'done' : c.noticesSent >= 2 ? (c.state === 'urgent' ? 'danger' : 'current') : 'pending'
|
||||||
? 'done'
|
|
||||||
: c.noticesSent >= 2
|
|
||||||
? c.state === 'urgent'
|
|
||||||
? 'danger'
|
|
||||||
: 'current'
|
|
||||||
: 'pending'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Debit Freeze',
|
label: 'Debit Freeze',
|
||||||
state: ['freeze', 'inop', 'dormant'].includes(c.state) ? 'done' : c.noticesSent >= 3 ? 'danger' : 'pending'
|
state: [
|
||||||
|
'freeze',
|
||||||
|
'inop',
|
||||||
|
'dormant'
|
||||||
|
].includes(c.state) ? 'done' : c.noticesSent >= 3 ? 'danger' : 'pending'
|
||||||
},
|
},
|
||||||
{ label: 'Inoperative', state: ['inop', 'dormant'].includes(c.state) ? 'done' : 'pending' },
|
{ label: 'Inoperative', state: [
|
||||||
|
'inop',
|
||||||
|
'dormant'
|
||||||
|
].includes(c.state) ? 'done' : 'pending' },
|
||||||
{ label: 'Dormant', state: c.state === 'dormant' ? 'danger' : 'pending' }
|
{ label: 'Dormant', state: c.state === 'dormant' ? 'danger' : 'pending' }
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -418,26 +699,30 @@ export class KycManagementComponent {
|
|||||||
|
|
||||||
stateLabel(state: string): string {
|
stateLabel(state: string): string {
|
||||||
return (
|
return (
|
||||||
{
|
(
|
||||||
alert: 'Alert Window',
|
{
|
||||||
freeze: 'Debit Freeze',
|
alert: 'Alert Window',
|
||||||
inop: 'Inoperative',
|
freeze: 'Debit Freeze',
|
||||||
dormant: 'Dormant',
|
inop: 'Inoperative',
|
||||||
urgent: 'Urgent Alert'
|
dormant: 'Dormant',
|
||||||
} as Record<string, string>
|
urgent: 'Urgent Alert'
|
||||||
)[state] || state;
|
} as Record<string, string>
|
||||||
|
)[state] || state
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
stateClass(state: string): string {
|
stateClass(state: string): string {
|
||||||
return (
|
return (
|
||||||
{
|
(
|
||||||
alert: 'sp-al',
|
{
|
||||||
freeze: 'sp-fr',
|
alert: 'sp-al',
|
||||||
inop: 'sp-in',
|
freeze: 'sp-fr',
|
||||||
dormant: 'sp-do',
|
inop: 'sp-in',
|
||||||
urgent: 'sp-fr'
|
dormant: 'sp-do',
|
||||||
} as Record<string, string>
|
urgent: 'sp-fr'
|
||||||
)[state] || 'sp-al';
|
} as Record<string, string>
|
||||||
|
)[state] || 'sp-al'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
riskClass(risk: string): string {
|
riskClass(risk: string): string {
|
||||||
|
|||||||
@@ -390,6 +390,7 @@ $mono: 'Roboto Mono', 'DM Mono', monospace;
|
|||||||
color: $text-muted;
|
color: $text-muted;
|
||||||
border-bottom: 1px solid $border;
|
border-bottom: 1px solid $border;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rows
|
// Rows
|
||||||
@@ -421,6 +422,7 @@ $mono: 'Roboto Mono', 'DM Mono', monospace;
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
color: $text;
|
color: $text;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
|
white-space: nowrap;
|
||||||
font-family:
|
font-family:
|
||||||
Inter,
|
Inter,
|
||||||
Roboto,
|
Roboto,
|
||||||
|
|||||||
Reference in New Issue
Block a user