Conflicts resolved in: - src/app/clients/clients-view/ckyc-tab/ckyc-tab.component.html - src/app/clients/clients-view/ckyc-tab/ckyc-tab.component.ts Kept dev's CKYC architecture (upload dialog, real per-artefact endpoints) and layered feature/bugfix's fixes on top: upload file validation, missing-file badge, silent preview download, and image/PDF view button. Also includes the CKYC "Image of Client" upload-state fix and the client-change state-leak fix in the same component. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
559 lines
22 KiB
HTML
559 lines
22 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/.
|
|
-->
|
|
|
|
<div class="ckyc-tab-container">
|
|
<!-- Loading State -->
|
|
@if (loading) {
|
|
<div class="ckyc-loading">
|
|
<mat-progress-spinner mode="indeterminate" diameter="48"></mat-progress-spinner>
|
|
<p>{{ 'labels.inputs.CKYC' | translate }}...</p>
|
|
</div>
|
|
}
|
|
|
|
@if (!loading) {
|
|
<!-- Header -->
|
|
<div class="ckyc-tab-header">
|
|
<div class="ckyc-tab-title">
|
|
<h3>{{ 'labels.heading.CKYC Verification' | translate }}</h3>
|
|
<span class="ckyc-badge">CKYC</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- CERSAI Sync Status hero -->
|
|
<div class="cersai-hero" [class.cersai-hero--synced]="ckycNumber" [class.cersai-hero--pending]="!ckycNumber">
|
|
<div class="cersai-hero__left">
|
|
<div class="cersai-hero__icon">
|
|
@if (ckycNumber) {
|
|
<fa-icon icon="check-double"></fa-icon>
|
|
} @else {
|
|
<fa-icon icon="hourglass-half"></fa-icon>
|
|
}
|
|
</div>
|
|
<div class="cersai-hero__text">
|
|
<div class="cersai-hero__status">
|
|
@if (ckycNumber) {
|
|
<span class="cersai-hero__tag">SYNCED WITH CERSAI</span>
|
|
} @else {
|
|
<span class="cersai-hero__tag cersai-hero__tag--pending">PENDING CERSAI SYNC</span>
|
|
}
|
|
</div>
|
|
@if (ckycNumber) {
|
|
<div class="cersai-hero__ckyc-label">CKYC Registry Number</div>
|
|
<div class="cersai-hero__ckyc-number">{{ ckycNumber }}</div>
|
|
<div class="cersai-hero__meta">
|
|
@if (ckycUploadedOn) {
|
|
<span>
|
|
<fa-icon icon="calendar-check"></fa-icon>
|
|
Uploaded on <strong>{{ ckycUploadedOn }}</strong>
|
|
</span>
|
|
}
|
|
@if (ckycBatchId) {
|
|
<span class="cersai-hero__sep">·</span>
|
|
<span>
|
|
<fa-icon icon="file-archive"></fa-icon>
|
|
Batch <strong>{{ ckycBatchId }}</strong>
|
|
</span>
|
|
}
|
|
</div>
|
|
} @else {
|
|
<div class="cersai-hero__ckyc-label">This client has not yet been synced to the CERSAI registry</div>
|
|
<div class="cersai-hero__hint">
|
|
Collect all 4 artefacts below, then create a batch from the Record Master to upload.
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
@if (ckycNumber) {
|
|
<div class="cersai-hero__pulse">
|
|
<span class="cersai-hero__pulse-dot"></span>
|
|
Live
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
<!-- KYC Verification Status (Aadhaar + PAN) -->
|
|
<div class="kyc-status-card" [class.kyc-status-card--complete]="kycComplete">
|
|
<div class="kyc-status-card__head">
|
|
<div class="kyc-status-card__title">
|
|
<fa-icon [icon]="kycComplete ? 'shield-alt' : 'user-shield'" class="kyc-status-card__icon"></fa-icon>
|
|
<span>KYC Verification</span>
|
|
</div>
|
|
@if (kycComplete) {
|
|
<span class="kyc-status-card__badge kyc-status-card__badge--ok">
|
|
<fa-icon icon="check-circle"></fa-icon>
|
|
KYC Done
|
|
</span>
|
|
} @else if (panVerified || aadhaarVerified) {
|
|
<span class="kyc-status-card__badge kyc-status-card__badge--partial">
|
|
<fa-icon icon="clock"></fa-icon>
|
|
Partially Verified
|
|
</span>
|
|
} @else {
|
|
<span class="kyc-status-card__badge kyc-status-card__badge--pending">
|
|
<fa-icon icon="exclamation-circle"></fa-icon>
|
|
Not Verified
|
|
</span>
|
|
}
|
|
</div>
|
|
|
|
<div class="kyc-status-card__body">
|
|
<div class="kyc-status-row">
|
|
<div class="kyc-status-row__label">
|
|
<fa-icon icon="id-card"></fa-icon>
|
|
<span>PAN</span>
|
|
</div>
|
|
@if (panVerified) {
|
|
<div class="kyc-status-row__value">
|
|
<span class="kyc-status-row__id">{{ panNumber || '—' }}</span>
|
|
@if (panHolderName) {
|
|
<span class="kyc-status-row__name">{{ panHolderName }}</span>
|
|
}
|
|
</div>
|
|
<span class="kyc-pill kyc-pill--ok"><fa-icon icon="check-circle"></fa-icon> Verified</span>
|
|
} @else {
|
|
<span class="kyc-status-row__value kyc-status-row__value--missing">{{ panNumber || 'Not provided' }}</span>
|
|
<span class="kyc-pill kyc-pill--pending"><fa-icon icon="times-circle"></fa-icon> Pending</span>
|
|
}
|
|
</div>
|
|
|
|
<div class="kyc-status-row">
|
|
<div class="kyc-status-row__label">
|
|
<fa-icon icon="fingerprint"></fa-icon>
|
|
<span>Aadhaar</span>
|
|
</div>
|
|
@if (aadhaarVerified) {
|
|
<div class="kyc-status-row__value">
|
|
<span class="kyc-status-row__id">{{ aadhaarMasked || '—' }}</span>
|
|
@if (aadhaarHolderName) {
|
|
<span class="kyc-status-row__name">{{ aadhaarHolderName }}</span>
|
|
}
|
|
</div>
|
|
<span class="kyc-pill kyc-pill--ok"><fa-icon icon="check-circle"></fa-icon> Verified</span>
|
|
} @else {
|
|
<span class="kyc-status-row__value kyc-status-row__value--missing">{{
|
|
aadhaarMasked || 'Not provided'
|
|
}}</span>
|
|
<span class="kyc-pill kyc-pill--pending"><fa-icon icon="times-circle"></fa-icon> Pending</span>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Client basic info -->
|
|
<div class="ckyc-info-grid">
|
|
<div class="ckyc-info-item">
|
|
<span class="ckyc-info-label"> <fa-icon icon="hashtag"></fa-icon> CIF Number </span>
|
|
<span class="ckyc-info-value ckyc-info-value--mono">{{ cifNumber || clientId }}</span>
|
|
</div>
|
|
|
|
<div class="ckyc-info-item">
|
|
<span class="ckyc-info-label"> <fa-icon icon="user"></fa-icon> Full Name </span>
|
|
<span class="ckyc-info-value">{{ clientName || '—' }}</span>
|
|
</div>
|
|
|
|
<div class="ckyc-info-item">
|
|
<span class="ckyc-info-label"> <fa-icon icon="envelope"></fa-icon> Email </span>
|
|
@if (clientEmail) {
|
|
<span class="ckyc-info-value">{{ clientEmail }}</span>
|
|
} @else {
|
|
<span class="ckyc-info-value ckyc-info-value--missing">No email on file</span>
|
|
}
|
|
</div>
|
|
|
|
<div class="ckyc-info-item">
|
|
<span class="ckyc-info-label"> <fa-icon icon="phone"></fa-icon> Mobile </span>
|
|
@if (clientMobile) {
|
|
<span class="ckyc-info-value">{{ clientMobile }}</span>
|
|
} @else {
|
|
<span class="ckyc-info-value ckyc-info-value--missing">No mobile on file</span>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Document Upload Section -->
|
|
<h4 class="ckyc-section-title">{{ 'labels.heading.CKYC Documents' | translate }}</h4>
|
|
|
|
@if (checkingExisting) {
|
|
<div class="ckyc-existing-loading">
|
|
<mat-progress-spinner diameter="18" mode="indeterminate"></mat-progress-spinner>
|
|
<span>Checking for already-uploaded artefacts…</span>
|
|
</div>
|
|
}
|
|
|
|
<div class="ckyc-upload-grid">
|
|
<!-- Address Proof Document -->
|
|
<mat-card class="ckyc-upload-card">
|
|
<mat-card-content>
|
|
<div class="ckyc-upload-header">
|
|
<mat-icon class="ckyc-upload-icon">home</mat-icon>
|
|
<span>{{ 'labels.inputs.Address Proof Document' | translate }}</span>
|
|
</div>
|
|
|
|
@if (existing.ADDRESS_PROOF.present) {
|
|
<div class="ckyc-existing">
|
|
<div class="ckyc-existing__head">
|
|
<fa-icon icon="check-circle" class="ckyc-existing__ok"></fa-icon>
|
|
<div>
|
|
<strong>Already available</strong>
|
|
<span class="ckyc-existing__source">from {{ existing.ADDRESS_PROOF.source }}</span>
|
|
@if (existing.ADDRESS_PROOF.previewUnavailable) {
|
|
<span class="ckyc-existing__warn">stored file unavailable</span>
|
|
}
|
|
</div>
|
|
</div>
|
|
@if (
|
|
(existing.ADDRESS_PROOF.previewUrl || existing.ADDRESS_PROOF.previewUrlBack) && isImage('ADDRESS_PROOF')
|
|
) {
|
|
<div class="ckyc-existing__thumbs">
|
|
@if (existing.ADDRESS_PROOF.previewUrl) {
|
|
<img
|
|
[src]="existing.ADDRESS_PROOF.previewUrl"
|
|
alt="Address proof scan - front"
|
|
class="ckyc-existing__thumb"
|
|
/>
|
|
}
|
|
@if (existing.ADDRESS_PROOF.previewUrlBack) {
|
|
<img
|
|
[src]="existing.ADDRESS_PROOF.previewUrlBack"
|
|
alt="Address proof scan - back"
|
|
class="ckyc-existing__thumb"
|
|
/>
|
|
}
|
|
</div>
|
|
}
|
|
@if (existing.ADDRESS_PROOF.previewUrl) {
|
|
<button
|
|
mat-stroked-button
|
|
type="button"
|
|
class="ckyc-existing__view"
|
|
(click)="openDocument('ADDRESS_PROOF')"
|
|
>
|
|
<fa-icon icon="eye"></fa-icon>
|
|
View document
|
|
</button>
|
|
}
|
|
<div class="ckyc-existing__meta">
|
|
<fa-icon icon="file-alt"></fa-icon>
|
|
<span>{{ existing.ADDRESS_PROOF.name }}</span>
|
|
@if (existing.ADDRESS_PROOF.documentKey) {
|
|
<span class="ckyc-existing__key">{{ existing.ADDRESS_PROOF.documentKey }}</span>
|
|
}
|
|
@if (existing.ADDRESS_PROOF.fileCount && existing.ADDRESS_PROOF.fileCount > 0) {
|
|
<span class="ckyc-existing__count">
|
|
{{ existing.ADDRESS_PROOF.fileCount }}
|
|
{{ existing.ADDRESS_PROOF.fileCount === 1 ? 'file' : 'files' }}
|
|
</span>
|
|
}
|
|
</div>
|
|
@if (cardDate('ADDRESS_PROOF', 'issue') || cardDate('ADDRESS_PROOF', 'expiry')) {
|
|
<div class="ckyc-existing__dates">
|
|
@if (cardDate('ADDRESS_PROOF', 'issue')) {
|
|
<span
|
|
><fa-icon icon="calendar-check"></fa-icon> Issued {{ cardDate('ADDRESS_PROOF', 'issue') }}</span
|
|
>
|
|
}
|
|
@if (cardDate('ADDRESS_PROOF', 'expiry')) {
|
|
<span
|
|
><fa-icon icon="calendar-check"></fa-icon> Expires {{ cardDate('ADDRESS_PROOF', 'expiry') }}</span
|
|
>
|
|
}
|
|
</div>
|
|
}
|
|
<button
|
|
mat-stroked-button
|
|
type="button"
|
|
class="ckyc-existing__replace"
|
|
(click)="openUploadDialog('ADDRESS_PROOF')"
|
|
>
|
|
<fa-icon icon="upload"></fa-icon>
|
|
Upload new version
|
|
</button>
|
|
</div>
|
|
} @else {
|
|
<div class="ckyc-missing">
|
|
<p class="ckyc-upload-hint">Not uploaded yet. Accepted formats: PNG, JPEG, JPG, PDF</p>
|
|
<button mat-raised-button color="primary" type="button" (click)="openUploadDialog('ADDRESS_PROOF')">
|
|
<fa-icon icon="upload"></fa-icon>
|
|
{{ 'labels.buttons.Upload' | translate }}
|
|
</button>
|
|
</div>
|
|
}
|
|
|
|
@if (uploading['ADDRESS_PROOF']) {
|
|
<div class="ckyc-uploading">
|
|
<mat-progress-spinner diameter="18" mode="indeterminate"></mat-progress-spinner>
|
|
<span>Uploading…</span>
|
|
</div>
|
|
}
|
|
@if (uploadErrors['ADDRESS_PROOF']) {
|
|
<div class="ckyc-upload-error">
|
|
<mat-icon>error_outline</mat-icon>
|
|
<span>{{ uploadErrors['ADDRESS_PROOF'] }}</span>
|
|
</div>
|
|
}
|
|
</mat-card-content>
|
|
</mat-card>
|
|
|
|
<!-- Photo Proof Document -->
|
|
<mat-card class="ckyc-upload-card">
|
|
<mat-card-content>
|
|
<div class="ckyc-upload-header">
|
|
<mat-icon class="ckyc-upload-icon">photo_camera</mat-icon>
|
|
<span>{{ 'labels.inputs.Photo Proof Document' | translate }}</span>
|
|
</div>
|
|
|
|
@if (existing.PHOTO_PROOF.present) {
|
|
<div class="ckyc-existing">
|
|
<div class="ckyc-existing__head">
|
|
<fa-icon icon="check-circle" class="ckyc-existing__ok"></fa-icon>
|
|
<div>
|
|
<strong>Already available</strong>
|
|
<span class="ckyc-existing__source">from {{ existing.PHOTO_PROOF.source }}</span>
|
|
@if (existing.PHOTO_PROOF.previewUnavailable) {
|
|
<span class="ckyc-existing__warn">stored file unavailable</span>
|
|
}
|
|
</div>
|
|
</div>
|
|
@if ((existing.PHOTO_PROOF.previewUrl || existing.PHOTO_PROOF.previewUrlBack) && isImage('PHOTO_PROOF')) {
|
|
<div class="ckyc-existing__thumbs">
|
|
@if (existing.PHOTO_PROOF.previewUrl) {
|
|
<img
|
|
[src]="existing.PHOTO_PROOF.previewUrl"
|
|
alt="ID proof scan - front"
|
|
class="ckyc-existing__thumb"
|
|
/>
|
|
}
|
|
@if (existing.PHOTO_PROOF.previewUrlBack) {
|
|
<img
|
|
[src]="existing.PHOTO_PROOF.previewUrlBack"
|
|
alt="ID proof scan - back"
|
|
class="ckyc-existing__thumb"
|
|
/>
|
|
}
|
|
</div>
|
|
}
|
|
@if (existing.PHOTO_PROOF.previewUrl) {
|
|
<button
|
|
mat-stroked-button
|
|
type="button"
|
|
class="ckyc-existing__view"
|
|
(click)="openDocument('PHOTO_PROOF')"
|
|
>
|
|
<fa-icon icon="eye"></fa-icon>
|
|
View document
|
|
</button>
|
|
}
|
|
<div class="ckyc-existing__meta">
|
|
<fa-icon icon="id-card"></fa-icon>
|
|
<span>{{ existing.PHOTO_PROOF.name }}</span>
|
|
@if (existing.PHOTO_PROOF.documentKey) {
|
|
<span class="ckyc-existing__key">{{ existing.PHOTO_PROOF.documentKey }}</span>
|
|
}
|
|
@if (existing.PHOTO_PROOF.fileCount && existing.PHOTO_PROOF.fileCount > 0) {
|
|
<span class="ckyc-existing__count">
|
|
{{ existing.PHOTO_PROOF.fileCount }} {{ existing.PHOTO_PROOF.fileCount === 1 ? 'file' : 'files' }}
|
|
</span>
|
|
}
|
|
</div>
|
|
@if (cardDate('PHOTO_PROOF', 'issue') || cardDate('PHOTO_PROOF', 'expiry')) {
|
|
<div class="ckyc-existing__dates">
|
|
@if (cardDate('PHOTO_PROOF', 'issue')) {
|
|
<span><fa-icon icon="calendar-check"></fa-icon> Issued {{ cardDate('PHOTO_PROOF', 'issue') }}</span>
|
|
}
|
|
@if (cardDate('PHOTO_PROOF', 'expiry')) {
|
|
<span
|
|
><fa-icon icon="calendar-check"></fa-icon> Expires {{ cardDate('PHOTO_PROOF', 'expiry') }}</span
|
|
>
|
|
}
|
|
</div>
|
|
}
|
|
<button
|
|
mat-stroked-button
|
|
type="button"
|
|
class="ckyc-existing__replace"
|
|
(click)="openUploadDialog('PHOTO_PROOF')"
|
|
>
|
|
<fa-icon icon="upload"></fa-icon>
|
|
Upload new version
|
|
</button>
|
|
</div>
|
|
} @else {
|
|
<div class="ckyc-missing">
|
|
<p class="ckyc-upload-hint">Not uploaded yet. Accepted formats: PNG, JPEG, JPG, PDF</p>
|
|
<button mat-raised-button color="primary" type="button" (click)="openUploadDialog('PHOTO_PROOF')">
|
|
<fa-icon icon="upload"></fa-icon>
|
|
{{ 'labels.buttons.Upload' | translate }}
|
|
</button>
|
|
</div>
|
|
}
|
|
|
|
@if (uploading['PHOTO_PROOF']) {
|
|
<div class="ckyc-uploading">
|
|
<mat-progress-spinner diameter="18" mode="indeterminate"></mat-progress-spinner>
|
|
<span>Uploading…</span>
|
|
</div>
|
|
}
|
|
@if (uploadErrors['PHOTO_PROOF']) {
|
|
<div class="ckyc-upload-error">
|
|
<mat-icon>error_outline</mat-icon>
|
|
<span>{{ uploadErrors['PHOTO_PROOF'] }}</span>
|
|
</div>
|
|
}
|
|
</mat-card-content>
|
|
</mat-card>
|
|
|
|
<!-- Client Image -->
|
|
<mat-card class="ckyc-upload-card">
|
|
<mat-card-content>
|
|
<div class="ckyc-upload-header">
|
|
<mat-icon class="ckyc-upload-icon">person</mat-icon>
|
|
<span>{{ 'labels.inputs.Image of Client' | translate }}</span>
|
|
</div>
|
|
|
|
@if (existing.CLIENT_IMAGE.present) {
|
|
<div class="ckyc-existing">
|
|
<div class="ckyc-existing__head">
|
|
<fa-icon icon="check-circle" class="ckyc-existing__ok"></fa-icon>
|
|
<div>
|
|
<strong>Already available</strong>
|
|
<span class="ckyc-existing__source">from {{ existing.CLIENT_IMAGE.source }}</span>
|
|
@if (existing.CLIENT_IMAGE.previewUnavailable) {
|
|
<span class="ckyc-existing__warn">stored file unavailable</span>
|
|
}
|
|
</div>
|
|
</div>
|
|
@if (existing.CLIENT_IMAGE.previewUrl && isImage('CLIENT_IMAGE')) {
|
|
<img [src]="existing.CLIENT_IMAGE.previewUrl" alt="Client photo" class="ckyc-existing__thumb" />
|
|
}
|
|
@if (existing.CLIENT_IMAGE.previewUrl) {
|
|
<button
|
|
mat-stroked-button
|
|
type="button"
|
|
class="ckyc-existing__view"
|
|
(click)="openDocument('CLIENT_IMAGE')"
|
|
>
|
|
<fa-icon icon="eye"></fa-icon>
|
|
View document
|
|
</button>
|
|
}
|
|
<button
|
|
mat-stroked-button
|
|
type="button"
|
|
class="ckyc-existing__replace"
|
|
(click)="openUploadDialog('CLIENT_IMAGE')"
|
|
>
|
|
<fa-icon icon="upload"></fa-icon>
|
|
Upload new version
|
|
</button>
|
|
</div>
|
|
} @else {
|
|
<div class="ckyc-missing">
|
|
<p class="ckyc-upload-hint">Not uploaded yet. Accepted formats: PNG, JPEG, JPG</p>
|
|
<button mat-raised-button color="primary" type="button" (click)="openUploadDialog('CLIENT_IMAGE')">
|
|
<fa-icon icon="upload"></fa-icon>
|
|
{{ 'labels.buttons.Upload' | translate }}
|
|
</button>
|
|
</div>
|
|
}
|
|
|
|
@if (uploading['CLIENT_IMAGE']) {
|
|
<div class="ckyc-uploading">
|
|
<mat-progress-spinner diameter="18" mode="indeterminate"></mat-progress-spinner>
|
|
<span>Uploading…</span>
|
|
</div>
|
|
}
|
|
@if (uploadErrors['CLIENT_IMAGE']) {
|
|
<div class="ckyc-upload-error">
|
|
<mat-icon>error_outline</mat-icon>
|
|
<span>{{ uploadErrors['CLIENT_IMAGE'] }}</span>
|
|
</div>
|
|
}
|
|
</mat-card-content>
|
|
</mat-card>
|
|
|
|
<!-- Client Signature -->
|
|
<mat-card class="ckyc-upload-card">
|
|
<mat-card-content>
|
|
<div class="ckyc-upload-header">
|
|
<mat-icon class="ckyc-upload-icon">draw</mat-icon>
|
|
<span>{{ 'labels.inputs.Signature of Client' | translate }}</span>
|
|
</div>
|
|
|
|
@if (existing.CLIENT_SIGNATURE.present) {
|
|
<div class="ckyc-existing">
|
|
<div class="ckyc-existing__head">
|
|
<fa-icon icon="check-circle" class="ckyc-existing__ok"></fa-icon>
|
|
<div>
|
|
<strong>Already available</strong>
|
|
<span class="ckyc-existing__source">from {{ existing.CLIENT_SIGNATURE.source }}</span>
|
|
@if (existing.CLIENT_SIGNATURE.previewUnavailable) {
|
|
<span class="ckyc-existing__warn">stored file unavailable</span>
|
|
}
|
|
</div>
|
|
</div>
|
|
@if (existing.CLIENT_SIGNATURE.previewUrl && isImage('CLIENT_SIGNATURE')) {
|
|
<img
|
|
[src]="existing.CLIENT_SIGNATURE.previewUrl"
|
|
alt="Client signature"
|
|
class="ckyc-existing__thumb ckyc-existing__thumb--wide"
|
|
/>
|
|
}
|
|
@if (existing.CLIENT_SIGNATURE.previewUrl) {
|
|
<button
|
|
mat-stroked-button
|
|
type="button"
|
|
class="ckyc-existing__view"
|
|
(click)="openDocument('CLIENT_SIGNATURE')"
|
|
>
|
|
<fa-icon icon="eye"></fa-icon>
|
|
View document
|
|
</button>
|
|
}
|
|
<div class="ckyc-existing__meta">
|
|
<fa-icon icon="file-signature"></fa-icon>
|
|
<span>{{ existing.CLIENT_SIGNATURE.name }}</span>
|
|
</div>
|
|
<button
|
|
mat-stroked-button
|
|
type="button"
|
|
class="ckyc-existing__replace"
|
|
(click)="openUploadDialog('CLIENT_SIGNATURE')"
|
|
>
|
|
<fa-icon icon="upload"></fa-icon>
|
|
Upload new version
|
|
</button>
|
|
</div>
|
|
} @else {
|
|
<div class="ckyc-missing">
|
|
<p class="ckyc-upload-hint">Not uploaded yet. Accepted formats: PNG, JPEG, JPG</p>
|
|
<button mat-raised-button color="primary" type="button" (click)="openUploadDialog('CLIENT_SIGNATURE')">
|
|
<fa-icon icon="upload"></fa-icon>
|
|
{{ 'labels.buttons.Upload' | translate }}
|
|
</button>
|
|
</div>
|
|
}
|
|
|
|
@if (uploading['CLIENT_SIGNATURE']) {
|
|
<div class="ckyc-uploading">
|
|
<mat-progress-spinner diameter="18" mode="indeterminate"></mat-progress-spinner>
|
|
<span>Uploading…</span>
|
|
</div>
|
|
}
|
|
@if (uploadErrors['CLIENT_SIGNATURE']) {
|
|
<div class="ckyc-upload-error">
|
|
<mat-icon>error_outline</mat-icon>
|
|
<span>{{ uploadErrors['CLIENT_SIGNATURE'] }}</span>
|
|
</div>
|
|
}
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
}
|
|
</div>
|