Files
cbsnexora/src/app/deposits/fixed-deposits/fixed-deposit-account-stepper/fixed-deposit-account-details-step/fixed-deposit-account-details-step.component.html
T
Jaanu423andClaude Sonnet 4.6 ad6f629c3f fix: nominee share & joint ownership validation across all account types
- Block 0% nominee share in all steppers (Savings, FD, RD, Current) —
  Add button disabled via isValid, addNominee() guards < 1, nominee-form
  error condition fixed for value=0
- Joint ownership: default primary share 50%, enforce min 1% on blur,
  max 100% on input with DOM clamp via $event, auto-redistribute
  co-holders proportionally when primary share changes,
  isJointOwnershipValid guards each holder >= 1
- Pending/Rejected account tabs: normalize date format to 22 May 2026
  for both array and string date values from API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 14:05:00 +05:30

899 lines
39 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!--
Copyright since 2025 Mifos Initiative
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->
<form [formGroup]="fixedDepositAccountDetailsForm">
<!-- ══ Account Details ══════════════════════════════════════════ -->
<div class="rad-section">
<div class="rad-section__header">
<i class="fas fa-info-circle"></i>
<h3>Account Details</h3>
</div>
<div class="rad-grid">
<mat-form-field appearance="outline" class="rad-field">
<mat-label>{{ 'labels.inputs.Product Name' | translate }}</mat-label>
<mat-select formControlName="productId" required>
@for (product of productData; track product) {
<mat-option [value]="product.id">{{ product.name }}</mat-option>
}
</mat-select>
<mat-error>
{{ 'labels.inputs.Product Name' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
@if (isProductSelected) {
<mat-form-field appearance="outline" class="rad-field" (click)="submittedOnDatePicker.open()">
<mat-label>{{ 'labels.inputs.Submitted On' | translate }}</mat-label>
<input
matInput
[min]="minDate"
[max]="maxDate"
[matDatepicker]="submittedOnDatePicker"
formControlName="submittedOnDate"
required
/>
<mat-datepicker-toggle matSuffix [for]="submittedOnDatePicker"></mat-datepicker-toggle>
<mat-datepicker #submittedOnDatePicker></mat-datepicker>
<mat-error>
{{ 'labels.inputs.Submitted On' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field appearance="outline" class="rad-field">
<mat-label>{{ 'labels.inputs.Field Officer' | translate }}</mat-label>
<mat-select formControlName="fieldOfficerId">
@for (officer of fieldOfficerData; track officer) {
<mat-option [value]="officer.id">{{ officer.displayName }}</mat-option>
}
</mat-select>
</mat-form-field>
<mat-form-field appearance="outline" class="rad-field">
<mat-label>{{ 'labels.inputs.External id' | translate }}</mat-label>
<input matInput formControlName="externalId" />
</mat-form-field>
}
</div>
</div>
@if (isProductSelected && productTemplate) {
<!-- ══ Product Classification (read-only) ══════════════════════ -->
<div class="rad-section rad-section--mt">
<div class="rad-section__header">
<i class="fas fa-tags"></i>
<h3>Product Classification</h3>
<span class="rad-badge">From Product</span>
</div>
<div class="rad-grid rad-grid--classification">
<mat-form-field appearance="outline" class="rad-field">
<mat-label>Account Type</mat-label>
<mat-select [(ngModel)]="selectedAccountType" [ngModelOptions]="{ standalone: true }">
@for (opt of accountTypeOptions; track opt) {
<mat-option [value]="opt">{{ opt }}</mat-option>
}
</mat-select>
</mat-form-field>
@if (productTemplate?.fdType) {
<mat-form-field appearance="outline" class="rad-field">
<mat-label>FD Type</mat-label>
<input matInput [value]="getFdTypeLabel(productTemplate.fdType)" readonly />
</mat-form-field>
}
<mat-form-field appearance="outline" class="rad-field">
<mat-label>Customer Segment</mat-label>
<mat-select [(ngModel)]="selectedCustomerSegment" [ngModelOptions]="{ standalone: true }">
@for (opt of customerSegmentOptions; track opt) {
<mat-option [value]="opt">{{ opt }}</mat-option>
}
</mat-select>
</mat-form-field>
<mat-form-field appearance="outline" class="rad-field">
<mat-label>Account No</mat-label>
<input
matInput
[value]="productTemplate?.previewAccountNo || fixedDepositsAccountTemplate?.accountNo || 'Auto-generated'"
readonly
/>
</mat-form-field>
@if (productTemplate.effectiveDate) {
<mat-form-field appearance="outline" class="rad-field">
<mat-label>Effective Date</mat-label>
<input matInput [value]="formatTemplateDate(productTemplate.effectiveDate)" readonly />
</mat-form-field>
}
@if (productTemplate.endDate) {
<mat-form-field appearance="outline" class="rad-field">
<mat-label>End Date</mat-label>
<input matInput [value]="formatTemplateDate(productTemplate.endDate)" readonly />
</mat-form-field>
}
<div class="rad-field rad-info-row">
<span class="rad-info-label">Deposit Account Link</span>
<span class="rad-badge" [class.rad-badge--yes]="productTemplate.shareLinkingEnabled">
{{ productTemplate.shareLinkingEnabled ? 'Yes' : 'No' }}
</span>
</div>
</div>
</div>
<!-- ══ Deposit Account Link ══════════════════════════════════════════ -->
@if (productTemplate?.shareLinkingEnabled) {
<div class="dal-card">
<div class="dal-card__header">
<div class="dal-card__header-left">
<div class="dal-card__icon">
<mat-icon>link</mat-icon>
</div>
<div>
<h3 class="dal-card__title">Deposit Account Link</h3>
<span class="dal-card__sub">Link an existing Savings or Current account to this FD</span>
</div>
</div>
</div>
<div class="dal-card__body">
@if (dalLoading) {
<div class="dal-loading">
<mat-icon class="dal-loading__icon">hourglass_top</mat-icon>
<span>Loading accounts…</span>
</div>
} @else if (selectedLinkedAccount) {
<!-- ── Selected Account Card ── -->
<div class="dal-selected">
<div class="dal-selected__info">
<span
class="dal-type-badge"
[class.dal-type-badge--savings]="selectedLinkedAccount.accountType === 'SAVINGS'"
[class.dal-type-badge--current]="selectedLinkedAccount.accountType === 'CURRENT'"
>
<mat-icon>{{
selectedLinkedAccount.accountType === 'SAVINGS' ? 'savings' : 'account_balance'
}}</mat-icon>
{{ selectedLinkedAccount.accountType === 'SAVINGS' ? 'Savings' : 'Current' }}
</span>
<div class="dal-selected__details">
<span class="dal-selected__accno">{{ selectedLinkedAccount.accountNo }}</span>
<span class="dal-selected__product">{{ selectedLinkedAccount.productName }}</span>
</div>
<div class="dal-selected__balance">
<span class="dal-selected__bal-label">Balance</span>
<span class="dal-selected__bal-amount"
>{{ selectedLinkedAccount.currencyCode }}
{{ selectedLinkedAccount.balance | number: '1.2-2' }}</span
>
</div>
</div>
<button
mat-stroked-button
color="warn"
type="button"
class="dal-change-btn"
(click)="clearLinkedAccount()"
>
<mat-icon>swap_horiz</mat-icon> Change
</button>
</div>
} @else {
<!-- ── Step 1: Choose account type ── -->
@if (!dalSelectedType) {
<div class="dal-type-step">
<p class="dal-type-step__label">Select account type to link:</p>
<div class="dal-type-grid">
<button type="button" class="dal-type-btn dal-type-btn--savings" (click)="selectDalType('SAVINGS')">
<mat-icon>savings</mat-icon>
<span class="dal-type-btn__name">Savings Account</span>
<span class="dal-type-btn__count"
>{{ dalAllSavings.length }} account{{ dalAllSavings.length !== 1 ? 's' : '' }}</span
>
</button>
<button type="button" class="dal-type-btn dal-type-btn--current" (click)="selectDalType('CURRENT')">
<mat-icon>account_balance</mat-icon>
<span class="dal-type-btn__name">Current Account</span>
<span class="dal-type-btn__count"
>{{ dalAllCurrent.length }} account{{ dalAllCurrent.length !== 1 ? 's' : '' }}</span
>
</button>
</div>
</div>
} @else {
<!-- ── Step 2: Search & pick from accounts ── -->
<div class="dal-picker">
<div class="dal-picker__topbar">
<button
type="button"
mat-icon-button
class="dal-back-btn"
matTooltip="Back"
(click)="dalSelectedType = null"
>
<mat-icon>arrow_back</mat-icon>
</button>
<span class="dal-picker__title">
<mat-icon>{{ dalSelectedType === 'SAVINGS' ? 'savings' : 'account_balance' }}</mat-icon>
{{ dalSelectedType === 'SAVINGS' ? 'Savings Accounts' : 'Current Accounts' }}
</span>
</div>
<mat-form-field appearance="outline" class="dal-search-field">
<mat-label>Search by Account No. or Product</mat-label>
<mat-icon matPrefix>search</mat-icon>
<input
matInput
[(ngModel)]="dalSearch"
[ngModelOptions]="{ standalone: true }"
placeholder="Type to filter…"
/>
@if (dalSearch) {
<button matSuffix mat-icon-button type="button" (click)="dalSearch = ''">
<mat-icon>clear</mat-icon>
</button>
}
</mat-form-field>
@if (dalFilteredAccounts.length === 0) {
<div class="dal-empty">
<mat-icon>search_off</mat-icon>
<span>No {{ dalSelectedType === 'SAVINGS' ? 'Savings' : 'Current' }} accounts found.</span>
</div>
} @else {
<div class="dal-list">
@for (account of dalFilteredAccounts; track account.id) {
<div
class="dal-item"
[class.dal-item--disabled]="account.status !== 'Active'"
(click)="selectLinkedAccount(account)"
>
<div class="dal-item__details">
<span class="dal-item__accno">{{ account.accountNo }}</span>
<span class="dal-item__product">{{ account.productName }}</span>
</div>
<div class="dal-item__right">
<span
class="dal-item__status"
[class.dal-item__status--active]="account.status === 'Active'"
>{{ account.status }}</span
>
<span class="dal-item__balance"
>{{ account.currencyCode }} {{ account.balance | number: '1.2-2' }}</span
>
</div>
<mat-icon class="dal-item__arrow">chevron_right</mat-icon>
</div>
}
</div>
}
</div>
}
}
</div>
</div>
}
}
<!-- ══ Status of Account (RBI) ═══════════════════════════════════════ -->
@if (isProductSelected) {
<div class="soa-card">
<div class="soa-card__header">
<div class="soa-card__header-left">
<div class="soa-card__icon">
<i class="fas fa-id-card"></i>
</div>
<div>
<h3 class="soa-card__title">Status of Account</h3>
<span class="soa-card__sub">As per RBI guidelines — select account holder type</span>
</div>
</div>
<span class="soa-pill">RBI Compliant</span>
</div>
<!-- Auto-detected client info bar -->
@if (clientDob) {
<div class="soa-client-info-bar">
<div class="soa-client-info-bar__item">
<mat-icon>cake</mat-icon>
<span
>Date of Birth: <strong>{{ formatTemplateDate(clientDob) }}</strong></span
>
</div>
<div class="soa-client-info-bar__item">
<mat-icon>person_pin</mat-icon>
<span
>Age: <strong>{{ clientAge }} years</strong></span
>
</div>
@if (clientAge !== null && clientAge < 18) {
<span class="soa-auto-pill soa-auto-pill--minor">
<mat-icon>child_care</mat-icon> Auto-detected: Minor
</span>
} @else if (clientAge !== null && clientAge >= 60) {
<span class="soa-auto-pill soa-auto-pill--senior">
<mat-icon>elderly</mat-icon> Auto-detected: Senior Citizen
</span>
} @else {
<span class="soa-auto-pill soa-auto-pill--ok"><mat-icon>check_circle</mat-icon> Age Verified</span>
}
</div>
}
<!-- Status selector tiles -->
<div class="soa-tiles">
@for (opt of accountStatusOptions; track opt.value) {
<button
type="button"
class="soa-tile"
[class.soa-tile--selected]="selectedAccountStatus === opt.value"
[class.soa-tile--disabled]="isTileDisabled(opt.value)"
[disabled]="isTileDisabled(opt.value)"
(click)="selectAccountStatus(opt.value)"
[title]="getTileTooltip(opt.value)"
>
<mat-icon class="soa-tile__icon" [style.color]="isTileDisabled(opt.value) ? '#cbd5e1' : opt.color">
{{ opt.icon }}
</mat-icon>
<span class="soa-tile__label">{{ opt.label }}</span>
@if (isTileDisabled(opt.value)) {
<span class="soa-tile__lock"><mat-icon>lock</mat-icon></span>
}
@if (selectedAccountStatus === opt.value) {
<mat-icon class="soa-tile__check">check_circle</mat-icon>
}
</button>
}
</div>
<!-- ── JOINT ACCOUNT ─────────────────────────────────────────── -->
@if (selectedAccountStatus === 'JOINT') {
<div class="soa-block">
<div class="soa-block__head">
<div class="soa-block__head-left">
<span class="soa-block__letter" style="background: #8b5cf6">A</span>
<div>
<span class="soa-block__title">Joint Account Holders</span>
<span class="soa-block__hint">Add all co-applicants linked to this joint FD account</span>
</div>
</div>
<button
mat-flat-button
color="primary"
type="button"
class="soa-add-btn"
[disabled]="totalJointSharePercentage >= 100"
(click)="openAddJointHolderDialog()"
>
<mat-icon>person_add</mat-icon> Add Holder
</button>
</div>
<div class="soa-table-wrap">
<table class="soa-tbl">
<thead>
<tr>
<th class="soa-th soa-th--sr">Sr.</th>
<th class="soa-th">Holder Name</th>
<th class="soa-th">CIF No.</th>
<th class="soa-th soa-th--center">Ownership %</th>
<th class="soa-th soa-th--center">Signing Authority</th>
<th class="soa-th soa-th--center">Role</th>
<th class="soa-th soa-th--center">Action</th>
</tr>
</thead>
<tbody>
<tr class="soa-tr soa-tr--primary">
<td class="soa-td soa-td--sr">1</td>
<td class="soa-td">
<div class="soa-client-cell">
<div class="soa-avatar soa-avatar--primary">
{{ primaryClientName ? primaryClientName[0].toUpperCase() : '?' }}
</div>
<div>
<span class="soa-client-name">{{ primaryClientName || 'Primary Holder' }}</span>
<span class="soa-primary-tag">Primary Account Holder</span>
</div>
</div>
</td>
<td class="soa-td">
<span class="soa-mono">{{ primaryClientCif || '—' }}</span>
</td>
<td class="soa-td soa-td--center">
<input
class="soa-pct-input"
type="number"
min="1"
max="100"
[(ngModel)]="primaryHolderShare"
[ngModelOptions]="{ standalone: true }"
placeholder="0"
(input)="onPrimaryShareInput($event)"
(blur)="onPrimaryShareBlur($event)"
/>
<span class="soa-pct-unit">%</span>
@if (primaryHolderShare !== null && primaryHolderShare !== undefined && primaryHolderShare < 1) {
<div class="soa-pct-error">Min 1%</div>
}
</td>
<td class="soa-td soa-td--center">
<span class="soa-sign-toggle soa-sign-toggle--mandatory">
<mat-icon>lock</mat-icon> Mandatory
</span>
</td>
<td class="soa-td soa-td--center">Primary Account Holder</td>
<td class="soa-td soa-td--center"><span class="soa-no-action">—</span></td>
</tr>
@for (h of jointHolders; track h; let i = $index) {
<tr class="soa-tr" [class.soa-tr--mandatory]="h.isMandatory">
<td class="soa-td soa-td--sr">{{ i + 2 }}</td>
<td class="soa-td">
<div class="soa-client-cell">
<div class="soa-avatar" [class.soa-avatar--mandatory]="h.isMandatory">
{{ h.clientName[0].toUpperCase() }}
</div>
<div>
<span class="soa-client-name">{{ h.clientName }}</span>
@if (h.isMandatory) {
<span class="soa-mandatory-tag">Mandatory Signatory</span>
}
</div>
</div>
</td>
<td class="soa-td">
<span class="soa-mono">{{ h.clientCif || '—' }}</span>
</td>
<td class="soa-td soa-td--center">
<span class="soa-pct-badge" [class.soa-pct-badge--full]="h.sharePercentage === 100">
{{ h.sharePercentage }}%
</span>
</td>
<td class="soa-td soa-td--center">
<button
type="button"
class="soa-sign-toggle"
[class.soa-sign-toggle--mandatory]="h.isMandatory"
[class.soa-sign-toggle--optional]="!h.isMandatory"
(click)="toggleJointHolderMandatory(h)"
>
<mat-icon>{{ h.isMandatory ? 'lock' : 'lock_open' }}</mat-icon>
{{ h.isMandatory ? 'Mandatory' : 'Optional' }}
</button>
</td>
<td class="soa-td soa-td--center">Co-Holder</td>
<td class="soa-td soa-td--center">
<button mat-icon-button color="warn" type="button" (click)="removeJointHolder(i)">
<mat-icon>delete_outline</mat-icon>
</button>
</td>
</tr>
}
</tbody>
<tfoot>
<tr class="soa-tr-total">
<td colspan="3" class="soa-td soa-td--total-label">Total Ownership</td>
<td class="soa-td soa-td--center">
<span
class="soa-pct-badge"
[class.soa-pct-badge--ok]="isJointOwnershipValid"
[class.soa-pct-badge--warn]="!isJointOwnershipValid"
>
{{ totalJointSharePercentage }}%
</span>
</td>
<td class="soa-td soa-td--center">
<span class="soa-mandatory-count">
<mat-icon>lock</mat-icon> {{ mandatoryJointCount + 1 }} Mandatory
</span>
</td>
<td></td>
<td></td>
</tr>
</tfoot>
</table>
</div>
@if (jointHolders.length === 0) {
<div class="soa-empty" style="margin-top: 8px">
<mat-icon>group_add</mat-icon>
<span>Click <strong>Add Holder</strong> to add joint account holders.</span>
</div>
}
@if (!isJointOwnershipValid) {
<div class="soa-alert soa-alert--warn" style="margin-top: 8px">
<mat-icon>warning_amber</mat-icon>
@if (totalJointSharePercentage !== 100) {
Total ownership is {{ totalJointSharePercentage }}%. It must equal 100%.
} @else {
Each holder must have at least 1% ownership share.
}
</div>
} @else {
<div class="soa-alert soa-alert--ok" style="margin-top: 8px">
<mat-icon>check_circle</mat-icon>
Ownership allocation is complete (100%).
</div>
}
</div>
<div class="soa-block soa-block--sep">
<div class="soa-block__head">
<div class="soa-block__head-left">
<span class="soa-block__letter" style="background: #7c3aed">B</span>
<div>
<span class="soa-block__title">Mode of Operation</span>
<span class="soa-block__hint">Auto-set from mandatory holders — override manually if required</span>
</div>
</div>
@if (modeOfOperation) {
<span class="soa-auto-badge"><mat-icon>auto_awesome</mat-icon> Auto</span>
}
</div>
@if (jointHolders.length === 0) {
<div class="soa-empty">
<mat-icon>how_to_vote</mat-icon>
<span>Add joint holders in Section A first.</span>
</div>
} @else {
<div class="soa-mode-grid">
@for (opt of modeOfOperationOptions; track opt.value) {
<button
type="button"
class="soa-mode-card"
[class.soa-mode-card--selected]="modeOfOperation === opt.value"
(click)="modeOfOperation = opt.value"
>
<mat-icon class="soa-mode-card__icon">{{ opt.icon }}</mat-icon>
<div class="soa-mode-card__code">{{ opt.label }}</div>
<div class="soa-mode-card__desc">{{ opt.sublabel }}</div>
@if (modeOfOperation === opt.value) {
<mat-icon class="soa-mode-card__check">check_circle</mat-icon>
}
</button>
}
</div>
<div class="soa-mode-summary" [class.soa-mode-summary--set]="modeOfOperation">
@if (modeOfOperation) {
<mat-icon>how_to_vote</mat-icon>
<span
>Mode of Operation: <strong>{{ selectedModeLabel }}</strong></span
>
<span class="soa-mode-summary__from">
({{ mandatoryJointCount }} Mandatory + {{ jointHolders.length - mandatoryJointCount }} Optional)
</span>
} @else {
<mat-icon>info</mat-icon>
<span>Set Mandatory/Optional for holders above to auto-select mode.</span>
}
</div>
}
</div>
}
<!-- ── MINOR ACCOUNT ─────────────────────────────────────────── -->
@if (selectedAccountStatus === 'MINOR') {
<div class="soa-block">
<div class="soa-block__head">
<div class="soa-block__head-left">
<span class="soa-block__letter" style="background: #f59e0b">
<mat-icon style="font-size: 14px; height: 14px; width: 14px">child_care</mat-icon>
</span>
<div>
<span class="soa-block__title">Minor Account Details</span>
<span class="soa-block__hint">As per RBI — guardian must be an existing registered client</span>
</div>
</div>
<span class="soa-pill soa-pill--minor">Guardian Required</span>
</div>
<div class="soa-minor-grid">
<mat-form-field appearance="outline" class="soa-field" (click)="minorDobPicker.open()">
<mat-label>Minor's Date of Birth</mat-label>
<input
matInput
[matDatepicker]="minorDobPicker"
[max]="maxDate"
[(ngModel)]="minorDob"
[ngModelOptions]="{ standalone: true }"
/>
<mat-datepicker-toggle matSuffix [for]="minorDobPicker"></mat-datepicker-toggle>
<mat-datepicker #minorDobPicker></mat-datepicker>
@if (clientDob) {
<mat-hint>Auto-filled from client profile</mat-hint>
}
</mat-form-field>
<mat-form-field appearance="outline" class="soa-field">
<mat-label>Age</mat-label>
<input matInput [value]="clientAge !== null ? clientAge + ' years' : '—'" readonly />
<mat-hint>Must be below 18 years</mat-hint>
</mat-form-field>
<mat-form-field appearance="outline" class="soa-field">
<mat-label>Date of Majority (Auto)</mat-label>
<input matInput [value]="majorityDate" readonly />
<mat-hint>Auto-calculated: DOB + 18 years</mat-hint>
</mat-form-field>
<mat-form-field appearance="outline" class="soa-field">
<mat-label>Guardian Relationship</mat-label>
<mat-select [(ngModel)]="guardianRelationship" [ngModelOptions]="{ standalone: true }">
@for (rel of guardianRelationshipOptions; track rel) {
<mat-option [value]="rel">{{ rel }}</mat-option>
}
</mat-select>
</mat-form-field>
</div>
<div class="soa-guardian-search">
<div class="soa-guardian-search__label">
<mat-icon>manage_accounts</mat-icon>
<span>Search &amp; Link Guardian (existing client)</span>
</div>
<mifosx-introducer-search
[excludedClientIds]="primaryClientId ? [primaryClientId] : []"
(introducerChange)="onGuardianChange($event)"
></mifosx-introducer-search>
@if (guardianName) {
<div class="soa-guardian-selected">
<mat-icon class="soa-guardian-selected__icon">verified_user</mat-icon>
<div>
<div class="soa-guardian-selected__name">{{ guardianName }}</div>
<div class="soa-guardian-selected__cif">CIF: {{ guardianCif || 'N/A' }}</div>
</div>
<span class="soa-pill soa-pill--ok">Guardian Linked</span>
</div>
}
</div>
<div class="soa-info-banner soa-info-banner--minor">
<mat-icon>info</mat-icon>
<ul>
<li>Minor below 10 years — Guardian must operate the account.</li>
<li>Minor above 10 years — Can operate independently (bank discretion).</li>
<li>Account must be converted to regular savings on attaining majority.</li>
<li>Fresh KYC of the minor must be done on majority.</li>
</ul>
</div>
</div>
}
<!-- ── SENIOR CITIZEN ────────────────────────────────────────── -->
@if (selectedAccountStatus === 'SENIOR_CITIZEN') {
<div class="soa-block">
<div class="soa-block__head">
<div class="soa-block__head-left">
<span class="soa-block__letter" style="background: #10b981">
<mat-icon style="font-size: 14px; height: 14px; width: 14px">elderly</mat-icon>
</span>
<div>
<span class="soa-block__title">Senior Citizen Account</span>
<span class="soa-block__hint">Age ≥ 60 years — eligible for preferential banking services</span>
</div>
</div>
<span class="soa-pill soa-pill--senior">Age ≥ 60</span>
</div>
<div class="soa-minor-grid" style="margin-bottom: 16px">
<mat-form-field appearance="outline" class="soa-field">
<mat-label>Date of Birth</mat-label>
<input matInput [value]="formatTemplateDate(clientDob)" readonly />
<mat-hint>From client profile</mat-hint>
</mat-form-field>
<mat-form-field appearance="outline" class="soa-field">
<mat-label>Age</mat-label>
<input matInput [value]="clientAge !== null ? clientAge + ' years' : '—'" readonly />
<mat-hint>Age ≥ 60 required for Senior Citizen</mat-hint>
</mat-form-field>
</div>
<div class="soa-sc-benefits">
<div class="soa-sc-benefit">
<mat-icon>priority_high</mat-icon>
<div>
<strong>Priority Service</strong>
<span>Dedicated counters / assisted banking at branches</span>
</div>
</div>
<div class="soa-sc-benefit">
<mat-icon>percent</mat-icon>
<div>
<strong>Preferential Interest Rate</strong>
<span>Additional 0.25%–0.50% on deposits (as per product)</span>
</div>
</div>
<div class="soa-sc-benefit">
<mat-icon>health_and_safety</mat-icon>
<div>
<strong>Doorstep Banking</strong>
<span>Eligible for home banking services (RBI circular)</span>
</div>
</div>
<div class="soa-sc-benefit">
<mat-icon>gavel</mat-icon>
<div>
<strong>Nomination Mandatory</strong>
<span>RBI mandate — ensure nomination is registered</span>
</div>
</div>
</div>
<div class="soa-info-banner soa-info-banner--senior">
<mat-icon>info</mat-icon>
<ul>
<li>Age proof (DOB document) mandatory at time of account opening.</li>
<li>Nomination registration is compulsory (Form DA-1).</li>
<li>Bank must offer dedicated helpline and priority grievance redressal.</li>
<li>Door-step banking services must be offered (RBI Master Direction 2023).</li>
</ul>
</div>
</div>
}
<!-- ── INDIVIDUAL MALE ───────────────────────────────────────── -->
@if (selectedAccountStatus === 'INDIVIDUAL_MALE') {
<div class="soa-block">
<div class="soa-block__head">
<div class="soa-block__head-left">
<span class="soa-block__letter" style="background: #3b82f6">
<mat-icon style="font-size: 14px; height: 14px; width: 14px">person</mat-icon>
</span>
<div>
<span class="soa-block__title">Individual Account (Male)</span>
<span class="soa-block__hint"
>Select special category if applicable — governs applicable schemes &amp; benefits</span
>
</div>
</div>
<span class="soa-pill" style="background: #dbeafe; color: #1d4ed8; border-color: #bfdbfe"
>Special Category</span
>
</div>
<div class="soa-category-grid">
@for (opt of specialCategoryOptions; track opt.value) {
<button
type="button"
class="soa-cat-tile"
[class.soa-cat-tile--selected]="selectedSpecialCategory === opt.value"
[class.soa-cat-tile--male]="true"
(click)="selectSpecialCategory(opt.value)"
>
<mat-icon class="soa-cat-tile__icon">{{ opt.icon }}</mat-icon>
<span class="soa-cat-tile__label">{{ opt.label }}</span>
@if (selectedSpecialCategory === opt.value) {
<mat-icon class="soa-cat-tile__check">check_circle</mat-icon>
}
</button>
}
</div>
<div class="soa-info-banner soa-info-banner--male">
<mat-icon>info</mat-icon>
<ul>
<li>Valid KYC documents required (Aadhaar / PAN / Passport).</li>
<li>Nomination registration is mandatory (Form DA-1).</li>
<li>Defence / Ex-Serviceman — eligible for special savings schemes (DSSP).</li>
<li>NRI — FCNR / NRE / NRO account rules apply as per FEMA guidelines.</li>
</ul>
</div>
</div>
}
<!-- ── INDIVIDUAL FEMALE ──────────────────────────────────────── -->
@if (selectedAccountStatus === 'INDIVIDUAL_FEMALE') {
<div class="soa-block">
<div class="soa-block__head">
<div class="soa-block__head-left">
<span class="soa-block__letter" style="background: #ec4899">
<mat-icon style="font-size: 14px; height: 14px; width: 14px">person_outline</mat-icon>
</span>
<div>
<span class="soa-block__title">Individual Account (Female)</span>
<span class="soa-block__hint"
>Select weaker section category if applicable — governs PMJDY &amp; priority schemes</span
>
</div>
</div>
<span class="soa-pill" style="background: #fce7f3; color: #be185d; border-color: #f9a8d4"
>Weaker Section</span
>
</div>
<div class="soa-category-grid">
@for (opt of weakerSectionOptions; track opt.value) {
<button
type="button"
class="soa-cat-tile"
[class.soa-cat-tile--selected]="selectedWeakerSection === opt.value"
[class.soa-cat-tile--female]="true"
(click)="selectWeakerSection(opt.value)"
>
<mat-icon class="soa-cat-tile__icon">{{ opt.icon }}</mat-icon>
<span class="soa-cat-tile__label">{{ opt.label }}</span>
@if (selectedWeakerSection === opt.value) {
<mat-icon class="soa-cat-tile__check">check_circle</mat-icon>
}
</button>
}
</div>
<div class="soa-info-banner soa-info-banner--female">
<mat-icon>info</mat-icon>
<ul>
<li>Valid KYC documents required (Aadhaar / PAN / Passport).</li>
<li>Nomination registration is mandatory (Form DA-1).</li>
<li>Eligible for PMJDY overdraft facilities (subject to rules).</li>
<li>Financial literacy & priority processing for women applicants.</li>
</ul>
</div>
</div>
}
<!-- ── SINGLE ACCOUNT ────────────────────────────────────────── -->
@if (selectedAccountStatus === 'SINGLE') {
<div class="soa-block">
<div class="soa-block__head">
<div class="soa-block__head-left">
<span class="soa-block__letter" style="background: #0891b2">
<mat-icon style="font-size: 14px; height: 14px; width: 14px">account_circle</mat-icon>
</span>
<div>
<span class="soa-block__title">Single Account</span>
<span class="soa-block__hint">Standard individual account operated by a single person</span>
</div>
</div>
<span class="soa-pill" style="background: #ecfeff; color: #0e7490; border-color: #cffafe"
>Single Holder</span
>
</div>
<div class="soa-info-banner soa-info-banner--single">
<mat-icon>info</mat-icon>
<ul>
<li>Only one primary holder allowed.</li>
<li>Nomination is highly recommended.</li>
<li>Full independent operation of account.</li>
<li>Convertible to joint account later if required.</li>
</ul>
</div>
</div>
}
</div>
}
@if (!hideButtons) {
<div class="layout-row align-center gap-2percent margin-t responsive-column">
<button mat-raised-button matStepperPrevious disabled>
<fa-icon icon="arrow-left" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Previous' | translate }}
</button>
<button
mat-raised-button
matStepperNext
[disabled]="
!fixedDepositAccountDetailsForm.get('productId')?.value ||
!fixedDepositAccountDetailsForm.get('submittedOnDate')?.value
"
>
{{ 'labels.buttons.Next' | translate }}
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
</div>
}
</form>