Files
cbsnexora/src/app/clients/client-stepper/client-family-members-step/client-family-members-step.component.html
T
niteshandClaude Sonnet 5 5fd7e1890e feat(clients): require Mother + Father/Caretaker as family members before activation
- Add hasMother/hasFather/hasCaretaker/familyRelationshipRulesMet to
  ClientFamilyMembersStepComponent, matched against the RELATIONSHIP code value label.
- Show two independent inline error banners (never merged into one message) when Mother, or
  both Father and Caretaker, are missing.
- Gate "Save & Next" and final Submit on this rule in both the create and edit client flows —
  the edit flow previously treated the Family tab as unconditionally optional.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-28 12:36:30 +05:30

169 lines
6.3 KiB
HTML

<!--
Copyright since 2025 Mifos Initiative
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->
<!--
Copyright since 2025 Mifos Initiative
-->
<div class="fm-step">
<!-- Step Header -->
<div class="step-header">
<div class="step-header__left">
<fa-icon icon="users" class="step-header__icon"></fa-icon>
<div>
@if (nomineeOnly) {
<h3 class="step-header__title">Nominees</h3>
<p class="step-header__sub">
Nominees for this client. Family members are not applicable for this entity type.
</p>
} @else {
<h3 class="step-header__title">Family Members</h3>
<p class="step-header__sub">Add family members and dependents of the client.</p>
}
</div>
</div>
</div>
@if (nomineeOnly) {
<div class="fm-step__empty">
<mat-icon class="fm-step__empty-icon">shield</mat-icon>
<span>Nominees are managed per account from the <strong>Nominees</strong> tab once accounts are opened.</span>
</div>
}
<!-- ═══ FAMILY MEMBERS ═══ -->
@if (!nomineeOnly) {
<div class="fm-step__header">
<div class="fm-step__title">
<fa-icon icon="users" class="fm-step__icon"></fa-icon>
<span>Family Members</span>
@if (clientFamilyMembers.length > 0) {
<span class="fm-step__count">{{ clientFamilyMembers.length }}</span>
}
</div>
@if (!readOnly) {
<button mat-flat-button color="primary" type="button" class="fm-step__add-btn" (click)="addFamilyMember()">
<mat-icon>add</mat-icon> Add Member
</button>
}
</div>
}
@if (!nomineeOnly && clientFamilyMembers.length === 0) {
<div class="fm-step__empty fm-step__empty--required">
<mat-icon class="fm-step__empty-icon">people_outline</mat-icon>
<span>No family members added yet.</span>
<span class="fm-step__empty-required">At least one family member is required.</span>
</div>
}
<!-- Mother requirement — shown independently of the Father/Caretaker check below -->
@if (!nomineeOnly && clientFamilyMembers.length > 0 && !hasMother) {
<div class="fm-step__empty fm-step__empty--required">
<mat-icon class="fm-step__empty-icon">error_outline</mat-icon>
<span class="fm-step__empty-required">Mother is required.</span>
</div>
}
<!-- Father-or-Caretaker requirement — shown independently of the Mother check above -->
@if (!nomineeOnly && clientFamilyMembers.length > 0 && !hasFather && !hasCaretaker) {
<div class="fm-step__empty fm-step__empty--required">
<mat-icon class="fm-step__empty-icon">error_outline</mat-icon>
<span class="fm-step__empty-required">Either Father or a Caretaker is required.</span>
</div>
}
<!-- Spouse hint for married clients -->
@if (!nomineeOnly && isMarried && !hasSpouse) {
<div class="fm-spouse-hint">
<mat-icon class="fm-spouse-hint__icon">favorite</mat-icon>
<span>Marital status is <strong>Married</strong>. Consider adding spouse as a family member.</span>
</div>
}
@if (!nomineeOnly && clientFamilyMembers.length > 0) {
<div class="fm-table">
<div class="fm-table__header">
<span class="fm-table__col fm-table__col--name">Name</span>
<span class="fm-table__col fm-table__col--rel">Relationship</span>
<span class="fm-table__col fm-table__col--dob">Date of Birth</span>
<span class="fm-table__col fm-table__col--id">Aadhaar / PAN</span>
<span class="fm-table__col fm-table__col--status">Alive</span>
<span class="fm-table__col fm-table__col--actions">Actions</span>
</div>
@for (member of clientFamilyMembers; track member; let i = $index) {
<div class="fm-table__row">
<span class="fm-table__col fm-table__col--name">
<mat-icon class="fm-table__avatar">{{ member.linkedClientId ? 'link' : 'person' }}</mat-icon>
<div class="fm-table__name-info">
<span class="fm-table__name-text">{{ member.firstName || member.displayName }}</span>
@if (member.linkedClientId) {
<span class="fm-table__linked-tag">Linked Client #{{ member.linkedClientId }}</span>
}
</div>
</span>
<span class="fm-table__col fm-table__col--rel">
{{ member.relationshipId | find: clientTemplate.familyMemberOptions.relationshipIdOptions : 'id' : 'name' }}
</span>
<span class="fm-table__col fm-table__col--dob">
{{ member.dateOfBirth ? (member.dateOfBirth | dateFormat) : '—' }}
</span>
<span class="fm-table__col fm-table__col--id fm-mono">
@if (member.panNumber) {
{{ member.panNumber }}
} @else if (member.aadhaarNumber) {
{{ member.aadhaarNumber }}
} @else {
—
}
</span>
<span class="fm-table__col fm-table__col--status">
@if (member.isAlive !== false) {
<span class="fm-alive-badge fm-alive-badge--yes">Yes</span>
} @else {
<span class="fm-alive-badge fm-alive-badge--no">No</span>
}
</span>
<span class="fm-table__col fm-table__col--actions">
<button
mat-icon-button
type="button"
(click)="viewFamilyMember(member)"
class="fm-action-btn"
matTooltip="View"
>
<mat-icon>visibility</mat-icon>
</button>
@if (!readOnly) {
<button
mat-icon-button
type="button"
(click)="editFamilyMember(member, i)"
class="fm-action-btn"
matTooltip="Edit"
>
<mat-icon>edit</mat-icon>
</button>
<button
mat-icon-button
type="button"
(click)="deleteFamilyMember(member.firstName, i)"
class="fm-action-btn fm-action-btn--delete"
matTooltip="Delete"
>
<mat-icon>delete</mat-icon>
</button>
}
</span>
</div>
}
</div>
}
</div>