@@ -12,7 +12,12 @@
|
||||
<h2>{{ 'labels.heading.Create Client' | translate }}</h2>
|
||||
</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 -->
|
||||
<mat-tab>
|
||||
<ng-template mat-tab-label>
|
||||
@@ -62,7 +67,8 @@
|
||||
</div>
|
||||
}
|
||||
<div class="tab-section">
|
||||
<mifosx-client-kyc-step #clientKyc
|
||||
<mifosx-client-kyc-step
|
||||
#clientKyc
|
||||
[isNonIndividual]="legalFormType === 2"
|
||||
[clientId]="createdClientId"
|
||||
[constitutionMeta]="clientGeneralStep?.selectedConstitution"
|
||||
@@ -127,13 +133,18 @@
|
||||
<mat-icon>edit</mat-icon> Edit
|
||||
</button>
|
||||
} @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
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<mifosx-client-india-address-step #clientIndiaAddress
|
||||
<mifosx-client-india-address-step
|
||||
#clientIndiaAddress
|
||||
[readOnly]="isTabReadOnly(addressTabIdx)"
|
||||
></mifosx-client-india-address-step>
|
||||
</div>
|
||||
@@ -155,13 +166,18 @@
|
||||
<mat-icon>edit</mat-icon> Edit
|
||||
</button>
|
||||
} @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
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<mifosx-client-family-members-step #clientFamilyMembers
|
||||
<mifosx-client-family-members-step
|
||||
#clientFamilyMembers
|
||||
[clientTemplate]="clientTemplate"
|
||||
[clientId]="createdClientId"
|
||||
[maritalStatusId]="clientGeneralStep?.createClientForm?.get('maritalStatusId')?.value"
|
||||
@@ -220,9 +236,19 @@
|
||||
}
|
||||
@if (selectedTabIndex < totalTabs - 1) {
|
||||
<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) {
|
||||
<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...
|
||||
} @else {
|
||||
<mat-icon class="m-r-6">save</mat-icon>
|
||||
|
||||
@@ -48,11 +48,11 @@
|
||||
.client-tabs {
|
||||
background: var(--md-sys-color-surface, #fff);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
box-shadow: 0 2px 8px rgb(0 0 0 / 8%);
|
||||
|
||||
::ng-deep {
|
||||
.mat-mdc-tab-header {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-bottom: 1px solid rgb(0 0 0 / 8%);
|
||||
}
|
||||
|
||||
.mat-mdc-tab {
|
||||
@@ -96,11 +96,11 @@
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 32px 16px;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
color: rgb(0 0 0 / 54%);
|
||||
font-size: 14px;
|
||||
|
||||
mat-icon {
|
||||
color: rgba(0, 0, 0, 0.38);
|
||||
color: rgb(0 0 0 / 38%);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
padding: 16px 0;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-top: 1px solid rgb(0 0 0 / 8%);
|
||||
}
|
||||
|
||||
.action-bar-right {
|
||||
@@ -119,7 +119,7 @@
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
color: rgb(0 0 0 / 60%);
|
||||
}
|
||||
|
||||
/* ─── Read-only tab state ─── */
|
||||
@@ -196,8 +196,9 @@
|
||||
::ng-deep .mdc-linear-progress__bar-inner {
|
||||
border-color: #fff !important;
|
||||
}
|
||||
|
||||
::ng-deep .mdc-linear-progress__buffer-bar {
|
||||
background-color: rgba(255, 255, 255, 0.3) !important;
|
||||
background-color: rgb(255 255 255 / 30%) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +223,9 @@
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
span { flex: 1; }
|
||||
span {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
button {
|
||||
flex-shrink: 0;
|
||||
|
||||
@@ -236,10 +236,14 @@ export class CreateClientComponent {
|
||||
}
|
||||
// Upload photo & signature
|
||||
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) {
|
||||
this.clientsService.uploadClientSignatureImage(clientId, this.clientKycStep.signatureFile).subscribe({ error: () => {} });
|
||||
this.clientsService
|
||||
.uploadClientSignatureImage(clientId, this.clientKycStep.signatureFile)
|
||||
.subscribe({ error: () => {} });
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -368,16 +372,27 @@ export class CreateClientComponent {
|
||||
* Finalize: upload photo/signature, save KYC, save addresses, then navigate.
|
||||
*/
|
||||
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
|
||||
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
|
||||
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
|
||||
@@ -409,16 +424,36 @@ export class CreateClientComponent {
|
||||
const addressData = this.clientIndiaAddressStep.addressData;
|
||||
// Map tab names to Fineract address type names (as defined in address template)
|
||||
const typeNameMap: Record<string, string[]> = {
|
||||
permanent: ['Permanent', 'Permanent Address'],
|
||||
current: ['Residential', 'Current', 'Current / Residential', 'Communication'],
|
||||
office: ['Office', 'Office / Work', 'Business', 'Work'],
|
||||
correspondence: ['Correspondence', 'Mailing', 'Postal']
|
||||
permanent: [
|
||||
'Permanent',
|
||||
'Permanent Address'
|
||||
],
|
||||
current: [
|
||||
'Residential',
|
||||
'Current',
|
||||
'Current / Residential',
|
||||
'Communication'
|
||||
],
|
||||
office: [
|
||||
'Office',
|
||||
'Office / Work',
|
||||
'Business',
|
||||
'Work'
|
||||
],
|
||||
correspondence: [
|
||||
'Correspondence',
|
||||
'Mailing',
|
||||
'Postal'
|
||||
]
|
||||
};
|
||||
|
||||
this.clientsService.getClientAddressTemplate().subscribe({
|
||||
next: (template: any) => {
|
||||
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;
|
||||
|
||||
// Find matching address type ID
|
||||
@@ -448,8 +483,8 @@ export class CreateClientComponent {
|
||||
|
||||
// Try to resolve state to stateProvinceId
|
||||
if ((addr as any).state && template?.stateProvinceIdOptions?.length) {
|
||||
const stateMatch = template.stateProvinceIdOptions.find((s: any) =>
|
||||
s.name?.toLowerCase() === (addr as any).state?.toLowerCase()
|
||||
const stateMatch = template.stateProvinceIdOptions.find(
|
||||
(s: any) => s.name?.toLowerCase() === (addr as any).state?.toLowerCase()
|
||||
);
|
||||
if (stateMatch) payload.stateProvinceId = stateMatch.id;
|
||||
}
|
||||
@@ -535,34 +570,98 @@ export class CreateClientComponent {
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
styles: [`
|
||||
.scd { background: #fff; border-radius: 12px; overflow: hidden; }
|
||||
.scd-header {
|
||||
display: flex; align-items: center; gap: 14px;
|
||||
padding: 20px 24px 16px;
|
||||
}
|
||||
.scd-header__icon-wrap {
|
||||
width: 44px; height: 44px; border-radius: 12px;
|
||||
background: #eff6ff; display: flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.scd-header__icon { color: #1074b9; font-size: 24px; width: 24px; height: 24px; }
|
||||
.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]
|
||||
styles: [
|
||||
`
|
||||
.scd {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.scd-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
padding: 20px 24px 16px;
|
||||
}
|
||||
.scd-header__icon-wrap {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 12px;
|
||||
background: #eff6ff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.scd-header__icon {
|
||||
color: #1074b9;
|
||||
font-size: 24px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
.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 {}
|
||||
|
||||
Reference in New Issue
Block a user