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>
|
||||
@if (createClientForm.get('legalFormId')?.value) {
|
||||
<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() }}
|
||||
</span>
|
||||
}
|
||||
@@ -67,12 +69,12 @@
|
||||
@if (getSelectedNationality().flagType === 'india') {
|
||||
<span class="nat-flag">
|
||||
<svg viewBox="0 0 36 24" class="nat-flag-svg">
|
||||
<rect width="36" height="8" fill="#FF9933"/>
|
||||
<rect y="8" width="36" height="8" fill="#FFFFFF"/>
|
||||
<rect y="16" width="36" height="8" fill="#138808"/>
|
||||
<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="0.7" fill="#000080"/>
|
||||
<rect width="36" height="8" fill="#FF9933" />
|
||||
<rect y="8" width="36" height="8" fill="#FFFFFF" />
|
||||
<rect y="16" width="36" height="8" fill="#138808" />
|
||||
<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="0.7" fill="#000080" />
|
||||
</svg>
|
||||
</span>
|
||||
} @else {
|
||||
@@ -88,12 +90,12 @@
|
||||
@if (nat.flagType === 'india') {
|
||||
<span class="nat-flag">
|
||||
<svg viewBox="0 0 36 24" class="nat-flag-svg">
|
||||
<rect width="36" height="8" fill="#FF9933"/>
|
||||
<rect y="8" width="36" height="8" fill="#FFFFFF"/>
|
||||
<rect y="16" width="36" height="8" fill="#138808"/>
|
||||
<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="0.7" fill="#000080"/>
|
||||
<rect width="36" height="8" fill="#FF9933" />
|
||||
<rect y="8" width="36" height="8" fill="#FFFFFF" />
|
||||
<rect y="16" width="36" height="8" fill="#138808" />
|
||||
<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="0.7" fill="#000080" />
|
||||
</svg>
|
||||
</span>
|
||||
} @else {
|
||||
@@ -129,7 +131,10 @@
|
||||
@if (createClientForm.get('fullname')) {
|
||||
<mat-form-field appearance="outline" class="form-field full-width">
|
||||
<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>
|
||||
<input matInput required formControlName="fullname" />
|
||||
@if (createClientForm.controls.fullname.hasError('required')) {
|
||||
@@ -150,30 +155,39 @@
|
||||
</div>
|
||||
<div class="verify-inline">
|
||||
@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"
|
||||
(click)="verifySanctions()">
|
||||
(click)="verifySanctions()"
|
||||
>
|
||||
<fa-icon icon="shield-alt" class="verify-name-icon"></fa-icon>
|
||||
Verify Entity
|
||||
</button>
|
||||
}
|
||||
@if (sanctionsVerified) {
|
||||
<span class="sanctions-citation">RBI KYC Master Direction (2016) — Section 51 & PMLA 2002</span>
|
||||
<span class="verify-status verified">
|
||||
<fa-icon icon="check-circle"></fa-icon> Verified
|
||||
</span>
|
||||
<mat-icon class="sanctions-info-icon"
|
||||
<span class="verify-status verified"> <fa-icon icon="check-circle"></fa-icon> Verified </span>
|
||||
<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."
|
||||
matTooltipClass="sanctions-tooltip">info</mat-icon>
|
||||
matTooltipClass="sanctions-tooltip"
|
||||
>info</mat-icon
|
||||
>
|
||||
}
|
||||
@if (sanctionsBlocked) {
|
||||
<span class="sanctions-citation">RBI KYC Master Direction (2016) — Section 51 & PMLA 2002</span>
|
||||
<span class="verify-status blocked">
|
||||
<fa-icon icon="exclamation-triangle"></fa-icon> Sanctions Match
|
||||
</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."
|
||||
matTooltipClass="sanctions-tooltip">info</mat-icon>
|
||||
matTooltipClass="sanctions-tooltip"
|
||||
>info</mat-icon
|
||||
>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -181,7 +195,9 @@
|
||||
}
|
||||
|
||||
<!-- 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">
|
||||
@if (createClientForm.get('salutationId') && salutationOptions?.length > 0) {
|
||||
<mat-form-field appearance="outline" class="name-field salutation-field-wide">
|
||||
@@ -213,7 +229,10 @@
|
||||
<mat-label>{{ 'labels.inputs.Middle Name' | translate }}</mat-label>
|
||||
<span matPrefix class="field-prefix-icon"><mat-icon>person_outline</mat-icon></span>
|
||||
<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-form-field>
|
||||
@@ -243,30 +262,39 @@
|
||||
</div>
|
||||
<div class="verify-inline">
|
||||
@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"
|
||||
(click)="verifySanctions()">
|
||||
(click)="verifySanctions()"
|
||||
>
|
||||
<fa-icon icon="shield-alt" class="verify-name-icon"></fa-icon>
|
||||
Verify Client
|
||||
</button>
|
||||
}
|
||||
@if (sanctionsVerified) {
|
||||
<span class="sanctions-citation">RBI KYC Master Direction (2016) — Section 51 & PMLA 2002</span>
|
||||
<span class="verify-status verified">
|
||||
<fa-icon icon="check-circle"></fa-icon> Verified
|
||||
</span>
|
||||
<mat-icon class="sanctions-info-icon"
|
||||
<span class="verify-status verified"> <fa-icon icon="check-circle"></fa-icon> Verified </span>
|
||||
<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."
|
||||
matTooltipClass="sanctions-tooltip">info</mat-icon>
|
||||
matTooltipClass="sanctions-tooltip"
|
||||
>info</mat-icon
|
||||
>
|
||||
}
|
||||
@if (sanctionsBlocked) {
|
||||
<span class="sanctions-citation">RBI KYC Master Direction (2016) — Section 51 & PMLA 2002</span>
|
||||
<span class="verify-status blocked">
|
||||
<fa-icon icon="exclamation-triangle"></fa-icon> Sanctions Match
|
||||
</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."
|
||||
matTooltipClass="sanctions-tooltip">info</mat-icon>
|
||||
matTooltipClass="sanctions-tooltip"
|
||||
>info</mat-icon
|
||||
>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -278,10 +306,18 @@
|
||||
<mat-form-field appearance="outline" class="form-field" (click)="dateOfBirthDatePicker.open()">
|
||||
<mat-label>Date of Birth</mat-label>
|
||||
<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 #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-form-field>
|
||||
@@ -324,7 +360,6 @@
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Minor / Guardian Mapping (mandatory if age < 10) -->
|
||||
@@ -341,9 +376,15 @@
|
||||
</div>
|
||||
<div class="guardian-section__header-right">
|
||||
<div class="guardian-section__age-chips">
|
||||
<span class="guardian-age-chip"><strong>{{ ageBreakdown.years }}</strong> yrs</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-age-chip"
|
||||
><strong>{{ ageBreakdown.years }}</strong> yrs</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>
|
||||
</div>
|
||||
@if (!selectedGuardian && !guardianLinking) {
|
||||
@@ -357,13 +398,14 @@
|
||||
|
||||
<!-- Body -->
|
||||
<div class="guardian-section__body" formGroupName="guardianDetails">
|
||||
|
||||
<!-- Empty state: no guardian linked, not linking -->
|
||||
@if (!selectedGuardian && !guardianLinking) {
|
||||
<div class="guardian-empty guardian-empty--required">
|
||||
<mat-icon class="guardian-empty__icon">person_off</mat-icon>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
@@ -377,22 +419,33 @@
|
||||
<mat-select required formControlName="guardianRelation">
|
||||
<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="LEGAL_GUARDIAN"><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="LEGAL_GUARDIAN"
|
||||
><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-select>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="guardian-search-wrapper guardian-search-col">
|
||||
<mat-form-field appearance="outline" class="guardian-search-field"
|
||||
[class.guardian-search-disabled]="!createClientForm.get('guardianDetails.guardianRelation')?.value">
|
||||
<mat-form-field
|
||||
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>
|
||||
<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)"
|
||||
(blur)="dismissGuardianSearch()"
|
||||
[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>
|
||||
|
||||
@if (guardianSearching) {
|
||||
@@ -413,11 +466,17 @@
|
||||
<div class="guardian-result-item__info">
|
||||
<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 }} }
|
||||
ID: {{ result.id }} · A/C: {{ result.accountNumber }} ·
|
||||
{{ result.officeName }}
|
||||
@if (result.dateOfBirth) {
|
||||
· DOB: {{ result.dateOfBirth | dateFormat }}
|
||||
}
|
||||
@if (result.fatherSpouseName) {
|
||||
· {{ result.fatherSpouseName }}
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
<span class="guardian-result-item__status"
|
||||
[class.active]="result.status?.value === 'Active'">
|
||||
<span class="guardian-result-item__status" [class.active]="result.status?.value === 'Active'">
|
||||
{{ result.status?.value }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -429,7 +488,13 @@
|
||||
}
|
||||
</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>
|
||||
</button>
|
||||
</div>
|
||||
@@ -453,8 +518,12 @@
|
||||
<span class="guardian-row__col guardian-row__col--photo">
|
||||
<div class="guardian-row__avatar" [class.has-photo]="selectedGuardian.profileImageUrl">
|
||||
@if (selectedGuardian.profileImageUrl) {
|
||||
<img [src]="selectedGuardian.profileImageUrl" alt="Photo" class="avatar-photo guardian-row__zoomable"
|
||||
(click)="zoomGuardianImage(selectedGuardian.profileImageUrl, 'Guardian Photo')" />
|
||||
<img
|
||||
[src]="selectedGuardian.profileImageUrl"
|
||||
alt="Photo"
|
||||
class="avatar-photo guardian-row__zoomable"
|
||||
(click)="zoomGuardianImage(selectedGuardian.profileImageUrl, 'Guardian Photo')"
|
||||
/>
|
||||
} @else {
|
||||
<fa-icon icon="user-shield"></fa-icon>
|
||||
}
|
||||
@@ -470,26 +539,40 @@
|
||||
</div>
|
||||
</span>
|
||||
<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 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 class="guardian-row__col guardian-row__col--status">
|
||||
<span class="guardian-row__status-badge"
|
||||
[class.guardian-row__status-badge--active]="selectedGuardian.status?.value === 'Active'">
|
||||
<span
|
||||
class="guardian-row__status-badge"
|
||||
[class.guardian-row__status-badge--active]="selectedGuardian.status?.value === 'Active'"
|
||||
>
|
||||
{{ selectedGuardian.status?.value || '-' }}
|
||||
</span>
|
||||
</span>
|
||||
<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"
|
||||
[matTooltip]="guardianExpanded ? 'Collapse' : 'View Details'">
|
||||
[matTooltip]="guardianExpanded ? 'Collapse' : 'View Details'"
|
||||
>
|
||||
<mat-icon>{{ guardianExpanded ? 'expand_less' : 'visibility' }}</mat-icon>
|
||||
</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()"
|
||||
matTooltip="Delete">
|
||||
matTooltip="Delete"
|
||||
>
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</span>
|
||||
@@ -506,16 +589,22 @@
|
||||
@if (selectedGuardian.panNumber) {
|
||||
<div class="guardian-expand__item">
|
||||
<span class="guardian-expand__label">PAN</span>
|
||||
<span class="guardian-expand__value">{{ selectedGuardian.panNumber }}
|
||||
@if (selectedGuardian.panVerified) { <mat-icon class="verify-tick-sm">check_circle</mat-icon> }
|
||||
<span class="guardian-expand__value"
|
||||
>{{ selectedGuardian.panNumber }}
|
||||
@if (selectedGuardian.panVerified) {
|
||||
<mat-icon class="verify-tick-sm">check_circle</mat-icon>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
@if (selectedGuardian.aadhaarMasked) {
|
||||
<div class="guardian-expand__item">
|
||||
<span class="guardian-expand__label">Aadhaar</span>
|
||||
<span class="guardian-expand__value">{{ selectedGuardian.aadhaarMasked }}
|
||||
@if (selectedGuardian.aadhaarVerified) { <mat-icon class="verify-tick-sm">check_circle</mat-icon> }
|
||||
<span class="guardian-expand__value"
|
||||
>{{ selectedGuardian.aadhaarMasked }}
|
||||
@if (selectedGuardian.aadhaarVerified) {
|
||||
<mat-icon class="verify-tick-sm">check_circle</mat-icon>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
@@ -535,8 +624,12 @@
|
||||
@if (selectedGuardian.signatureUrl) {
|
||||
<div class="guardian-expand__sig">
|
||||
<span class="guardian-expand__label">Specimen Signature</span>
|
||||
<img [src]="selectedGuardian.signatureUrl" alt="Signature" class="guardian-expand__sig-img guardian-row__zoomable"
|
||||
(click)="zoomGuardianImage(selectedGuardian.signatureUrl, 'Specimen Signature')" />
|
||||
<img
|
||||
[src]="selectedGuardian.signatureUrl"
|
||||
alt="Signature"
|
||||
class="guardian-expand__sig-img guardian-row__zoomable"
|
||||
(click)="zoomGuardianImage(selectedGuardian.signatureUrl, 'Specimen Signature')"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -549,7 +642,7 @@
|
||||
|
||||
<!-- Non-Individual Details -->
|
||||
@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-label>Constitution Type</mat-label>
|
||||
<mat-select formControlName="constitutionId" required>
|
||||
@@ -607,7 +700,10 @@
|
||||
</h4>
|
||||
<div class="minor-info-bar">
|
||||
<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>
|
||||
|
||||
<!-- Signatory List Table -->
|
||||
@@ -638,27 +734,45 @@
|
||||
<span class="sig-table__col sig-table__col--name">
|
||||
<strong>{{ sig.displayName }}</strong>
|
||||
@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 class="sig-table__col sig-table__col--id">{{ sig.cifNumber || sig.id }}</span>
|
||||
<span class="sig-table__col sig-table__col--pan">
|
||||
{{ 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 class="sig-table__col sig-table__col--din">
|
||||
@if (sig.dinNumber) {
|
||||
{{ sig.dinNumber }}
|
||||
@if (sig.dinVerified) { <mat-icon class="verify-tick-sm">check_circle</mat-icon> }
|
||||
@if (!sig.dinVerified) { <mat-icon class="verify-cross-sm">cancel</mat-icon> }
|
||||
@if (sig.dinVerified) {
|
||||
<mat-icon class="verify-tick-sm">check_circle</mat-icon>
|
||||
}
|
||||
@if (!sig.dinVerified) {
|
||||
<mat-icon class="verify-cross-sm">cancel</mat-icon>
|
||||
}
|
||||
} @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
|
||||
</button>
|
||||
}
|
||||
</span>
|
||||
<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 class="sig-table__col sig-table__col--actions">
|
||||
<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-label>Add Signatory — Search by Name or Client ID</mat-label>
|
||||
<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)"
|
||||
(blur)="dismissSignatorySearch()"
|
||||
placeholder="Type name or client ID..." autocomplete="off" />
|
||||
placeholder="Type name or client ID..."
|
||||
autocomplete="off"
|
||||
/>
|
||||
</mat-form-field>
|
||||
@if (signatorySearching) {
|
||||
<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__info">
|
||||
<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>
|
||||
<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>
|
||||
@@ -728,7 +857,6 @@
|
||||
<textarea matInput formControlName="remarks" cdkTextareaAutosize cdkAutosizeMinRows="2"></textarea>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -737,9 +865,12 @@
|
||||
<h4 class="section-title">
|
||||
<fa-icon icon="mobile-alt" class="section-icon"></fa-icon>
|
||||
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)"
|
||||
matTooltipPosition="above">info</mat-icon>
|
||||
matTooltipPosition="above"
|
||||
>info</mat-icon
|
||||
>
|
||||
</h4>
|
||||
|
||||
<div class="form-grid">
|
||||
@@ -747,21 +878,35 @@
|
||||
<mat-form-field appearance="outline" class="form-field">
|
||||
<mat-label>{{ 'labels.inputs.Mobile No' | translate }}</mat-label>
|
||||
<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()"
|
||||
(paste)="$event.preventDefault()" />
|
||||
(paste)="$event.preventDefault()"
|
||||
/>
|
||||
@if (createClientForm.get('mobileNo')?.hasError('required') && createClientForm.get('mobileNo')?.touched) {
|
||||
<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-form-field>
|
||||
|
||||
<div class="form-field mobile-verify-row">
|
||||
@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"
|
||||
(click)="verifyWithDIP()">
|
||||
(click)="verifyWithDIP()"
|
||||
>
|
||||
<fa-icon icon="shield-alt" class="m-r-10"></fa-icon>
|
||||
Verify with DIP
|
||||
</button>
|
||||
@@ -774,19 +919,33 @@
|
||||
<mat-form-field appearance="outline" class="form-field">
|
||||
<mat-label>Alternate Mobile No</mat-label>
|
||||
<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()"
|
||||
(paste)="$event.preventDefault()" />
|
||||
@if (createClientForm.get('alternateMobileNo')?.hasError('pattern') && createClientForm.get('alternateMobileNo')?.touched) {
|
||||
(paste)="$event.preventDefault()"
|
||||
/>
|
||||
@if (
|
||||
createClientForm.get('alternateMobileNo')?.hasError('pattern') &&
|
||||
createClientForm.get('alternateMobileNo')?.touched
|
||||
) {
|
||||
<mat-error>Enter valid 10-digit number (starts with 6-9)</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<div class="form-field mobile-verify-row">
|
||||
@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"
|
||||
(click)="verifyAlternateDIP()">
|
||||
(click)="verifyAlternateDIP()"
|
||||
>
|
||||
<fa-icon icon="shield-alt" class="m-r-10"></fa-icon>
|
||||
Verify with DIP
|
||||
</button>
|
||||
@@ -800,21 +959,27 @@
|
||||
<mat-label>{{ 'labels.inputs.Email Address' | translate }}</mat-label>
|
||||
<span matPrefix class="field-prefix-icon"><mat-icon>email</mat-icon></span>
|
||||
<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>
|
||||
} @else if (createClientForm.get('emailAddress')?.invalid && createClientForm.get('emailAddress')?.touched) {
|
||||
<mat-error>Enter a valid email (e.g. name@example.com)</mat-error>
|
||||
}
|
||||
</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-label>Marital Status</mat-label>
|
||||
<mat-select formControlName="maritalStatusId">
|
||||
<mat-select-trigger>
|
||||
@if (getSelectedMaritalStatus()) {
|
||||
<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 }}
|
||||
</span>
|
||||
}
|
||||
@@ -833,83 +998,249 @@
|
||||
</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) -->
|
||||
@if (createClientForm.get('legalFormId')?.value === LegalFormId.PERSON) {
|
||||
<div class="section-block">
|
||||
<h4 class="section-title">
|
||||
<fa-icon icon="chart-line" class="section-icon"></fa-icon>
|
||||
Financial & Classification
|
||||
</h4>
|
||||
<div class="form-grid">
|
||||
|
||||
|
||||
<mat-form-field appearance="outline" class="form-field">
|
||||
<mat-label>{{ 'labels.inputs.Occupation Category' | translate }}</mat-label>
|
||||
<mat-select formControlName="occupationCategoryId">
|
||||
<mat-select-trigger>
|
||||
@if (getSelectedOccupationCategory()) {
|
||||
<span class="occ-option">
|
||||
<mat-icon class="occ-option-icon">{{ getOccupationCategoryIcon(getSelectedOccupationCategory().name) }}</mat-icon>
|
||||
{{ getSelectedOccupationCategory().name }}
|
||||
</span>
|
||||
<div class="section-block">
|
||||
<h4 class="section-title">
|
||||
<fa-icon icon="chart-line" class="section-icon"></fa-icon>
|
||||
Financial & Classification
|
||||
</h4>
|
||||
<div class="form-grid">
|
||||
<mat-form-field appearance="outline" class="form-field">
|
||||
<mat-label>{{ 'labels.inputs.Occupation Category' | translate }}</mat-label>
|
||||
<mat-select formControlName="occupationCategoryId">
|
||||
<mat-select-trigger>
|
||||
@if (getSelectedOccupationCategory()) {
|
||||
<span class="occ-option">
|
||||
<mat-icon class="occ-option-icon">{{
|
||||
getOccupationCategoryIcon(getSelectedOccupationCategory().name)
|
||||
}}</mat-icon>
|
||||
{{ getSelectedOccupationCategory().name }}
|
||||
</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>
|
||||
@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>
|
||||
</mat-form-field>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="form-field">
|
||||
<mat-label>{{ 'labels.inputs.Occupation' | translate }}</mat-label>
|
||||
<mat-select formControlName="occupationId">
|
||||
<mat-select-trigger>
|
||||
@if (getSelectedOccupation()) {
|
||||
<span class="occ-option">
|
||||
<mat-icon class="occ-option-icon">{{ getOccupationIcon(getSelectedOccupation().name) }}</mat-icon>
|
||||
{{ getSelectedOccupation().name }}
|
||||
</span>
|
||||
<mat-form-field appearance="outline" class="form-field">
|
||||
<mat-label>{{ 'labels.inputs.Occupation' | translate }}</mat-label>
|
||||
<mat-select formControlName="occupationId">
|
||||
<mat-select-trigger>
|
||||
@if (getSelectedOccupation()) {
|
||||
<span class="occ-option">
|
||||
<mat-icon class="occ-option-icon">{{ getOccupationIcon(getSelectedOccupation().name) }}</mat-icon>
|
||||
{{ getSelectedOccupation().name }}
|
||||
</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>
|
||||
@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>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="form-field">
|
||||
<mat-label>Monthly Income</mat-label>
|
||||
<span matPrefix class="rupee-prefix">₹</span>
|
||||
<input matInput type="number" formControlName="monthlyIncome" min="0" />
|
||||
@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-label>Monthly Income</mat-label>
|
||||
<span matPrefix class="rupee-prefix">₹</span>
|
||||
<input matInput type="number" formControlName="monthlyIncome" min="0" />
|
||||
@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-form-field>
|
||||
<mat-form-field appearance="outline" class="form-field">
|
||||
<mat-label>Annual Turnover (Last FY)</mat-label>
|
||||
<span matPrefix class="rupee-prefix">₹</span>
|
||||
<input matInput type="number" formControlName="annualTurnover" min="0" />
|
||||
@if (
|
||||
createClientForm.get('annualTurnover')?.hasError('pattern') &&
|
||||
createClientForm.get('annualTurnover')?.touched
|
||||
) {
|
||||
<mat-error>Enter a valid amount</mat-error>
|
||||
} @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-label>Annual Turnover (Last FY)</mat-label>
|
||||
<span matPrefix class="rupee-prefix">₹</span>
|
||||
<input matInput type="number" formControlName="annualTurnover" min="0" />
|
||||
@if (createClientForm.get('annualTurnover')?.hasError('pattern') && createClientForm.get('annualTurnover')?.touched) {
|
||||
<mat-error>Enter a valid amount</mat-error>
|
||||
} @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-label>Agriculture Income</mat-label>
|
||||
<span matPrefix class="rupee-prefix">₹</span>
|
||||
<input matInput type="number" formControlName="agricultureIncome" min="0" />
|
||||
@if (
|
||||
createClientForm.get('agricultureIncome')?.hasError('pattern') &&
|
||||
createClientForm.get('agricultureIncome')?.touched
|
||||
) {
|
||||
<mat-error>Enter a valid amount</mat-error>
|
||||
} @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>
|
||||
}
|
||||
|
||||
<!-- submittedOnDate is set automatically via form default (business date) -->
|
||||
|
||||
Reference in New Issue
Block a user