{{-- Client 360 — tab panels --}} @if (! empty($entity360Fragment)) @php // Never fall back to request ?tab= — that query is shared with the workspace URL // and will paint Payments into the Applications panel after a tab switch. $fragmentTab = trim((string) ($e360PanelFragmentTab ?? $entity360FragmentTab ?? '')); @endphp
@if ($fragmentTab !== '') @if ($fragmentTab === 'applications')
@php $apps = $clientApplications ?? collect(); $createUrl = route('loan.book.applications.create', ['loan_client_id' => $loan_client->id, 'lock_client' => 1]); @endphp

Applications

@if (($loan_client->kind ?? null) === \App\Models\LoanClient::KIND_CLIENT) New application @endif
@forelse ($apps as $application) @php $stage = (string) $application->stage; $loanStatus = (string) ($application->loan?->status ?? ''); $awaitingDisbursement = $application->isAwaitingTreasuryDisbursement(); $stageLabel = $awaitingDisbursement ? 'Awaiting disbursement' : str($stage)->headline(); $stageTone = match (true) { $awaitingDisbursement => 'border-sky-200 bg-sky-100 text-sky-900', $stage === \App\Models\LoanBookApplication::STAGE_DISBURSED => 'border-emerald-200 bg-emerald-100 text-emerald-800', $stage === \App\Models\LoanBookApplication::STAGE_DECLINED => 'border-rose-200 bg-rose-100 text-rose-800', $stage === \App\Models\LoanBookApplication::STAGE_CREDIT_REVIEW => 'border-amber-200 bg-amber-100 text-amber-900', default => 'border-slate-200 bg-slate-100 text-slate-700', }; @endphp @empty @endforelse
Reference Product Amount Stage Workflow Borrower Updated Details Actions
{{ $application->reference }} {{ $application->product_name ?: '—' }} KES {{ number_format((float) $application->displayPrincipal(), 0) }} {{ $stageLabel }} {{ $application->workflow_status ? str($application->workflow_status)->headline() : '—' }} {{ str($application->borrower_category ?? '—')->replace('_', ' ')->title() }} {{ optional($application->updated_at)->format('M j, Y') ?? '—' }} View loan · Application form @if ($application->requiresRetailAppraisal()) · Appraisal sheet · Approval history @endif @if ($application->loan) · Disbursement @endif Open @if (in_array($stage, [\App\Models\LoanBookApplication::STAGE_SUBMITTED, \App\Models\LoanBookApplication::STAGE_CREDIT_REVIEW], true)) · Edit @endif
None
@endif @if ($fragmentTab === 'loans')
@if (($maxArrearsDays ?? 0) > 0 || ($totalArrearsAmount ?? 0) > 0)
Arrears · {{ $maxArrearsDays }} DPD @if (($totalArrearsAmount ?? 0) > 0) · KES {{ number_format($totalArrearsAmount, 0) }} @endif
@endif @include('loan.clients.partials._loan-table', [ 'loans' => $loanHistory, 'tableTitle' => 'Loans', 'emptyMessage' => 'No loans found for this client.', 'installmentProgressByLoan' => $installmentProgressByLoan ?? [], ])
@endif @if ($fragmentTab === 'payments')

Payments

@if ($paymentsLoanFilter ?? null)

@if ($paymentsLoanFilterLocked ?? false) Loan adjustment in progress — showing repayments for {{ $paymentsLoanFilter->loan_number }} only. Reverse newest on this loan first. @else Showing repayments for loan {{ $paymentsLoanFilter->loan_number }}. Reverse newest first. @endif

@endif
@if (($paymentsLoanFilter ?? null) && ! ($paymentsLoanFilterLocked ?? false)) All client payments @endif
@php $previousPaymentLoanId = null; @endphp @forelse (($recentPayments ?? collect()) as $payment) @php $status = ucfirst((string) ($payment->status ?? 'processed')); $txn = $payment->receiptNumber() ?? ('TXN-' . $payment->id); $currentPaymentLoanId = (int) ($payment->loan_book_loan_id ?? $payment->loan?->id ?? 0); $isNewLoanPaymentGroup = $previousPaymentLoanId !== null && $currentPaymentLoanId !== $previousPaymentLoanId; $previousPaymentLoanId = $currentPaymentLoanId; @endphp td]:border-b [&>td]:border-r [&>td]:border-slate-200 [&>td:last-child]:border-r-0', '[&>td]:border-t-2 [&>td]:border-t-slate-400' => $isNewLoanPaymentGroup, ]) x-show="mobileMatchesSearch(@js($txn), @js($payment->loan?->loan_number), @js($status))" > @empty @endforelse
Transaction Loan Amount Method Status Time Actions
{{ $txn }} {{ $payment->loan?->loan_number ?? '—' }} KES {{ number_format((float) ($payment->amount ?? 0), 0) }} {{ $payment->payment_method ?? $payment->payment_channel ?? 'Manual payment' }} {{ $status }} {{ optional($payment->transaction_at)->format('M j, Y g:i A') ?? optional($payment->created_at)->format('M j, Y g:i A') ?? '—' }} @if ( auth()->user()?->hasLoanPermission('payments.reverse.request') && auth()->user()?->hasLoanPermission('payments.reverse.approve') && $payment->payment_kind !== \App\Models\LoanBookPayment::KIND_C2B_REVERSAL && ! (bool) $payment->funded_from_wallet && (int) ($latestReversiblePaymentId ?? 0) === (int) $payment->id ) Reverse @else @php $reverseLockHint = ($paymentsLoanFilterLocked ?? false) ? 'During loan adjustment: reverse the latest posted repayment on this loan only (newest first). Re-post from Unposted after saving terms — do not reverse re-posted cash.' : 'Only the latest posted repayment can be reversed. Reverse newer payments first.'; @endphp Locked @endif
None
@endif @if ($fragmentTab === 'documents')

Documents

Add document
@forelse ($documents as $document) @php $docUrl = $loan_client->kycImageUrl($document['path']); $docLabel = (string) ($document['type'] ?? 'Document'); $docDate = (string) ($document['date'] ?? ''); @endphp @empty @endforelse
Preview Document type Upload date Actions
{{ $docLabel }} {{ $docDate !== '' ? $docDate : '—' }} View full size
None
@endif @if ($fragmentTab === 'guarantors')
@if (auth()->user()?->hasLoanPermission('applications.create'))
New application
@endif @if (($profileGuarantors ?? collect())->isNotEmpty())

Profile

@foreach ($profileGuarantors as $profileGuarantor) @endforeach
Slot Name Phone Relationship ID Address
{{ $profileGuarantor['slot'] }} {{ $profileGuarantor['full_name'] }} @if ($profileGuarantor['phone'] !== '') @else — @endif {{ $profileGuarantor['relationship'] !== '' ? $profileGuarantor['relationship'] : '—' }} {{ $profileGuarantor['id_number'] !== '' ? $profileGuarantor['id_number'] : '—' }} {{ $profileGuarantor['address'] !== '' ? $profileGuarantor['address'] : '—' }}
@endif

On loans

@forelse (($loanGuarantorsForClient ?? collect()) as $guarantor) @empty @endforelse
Name Phone Loan Status Relationship KYC
{{ $guarantor->full_name }} @if ($guarantor->phone)@else — @endif {{ $guarantor->loan?->loan_number ?: ($guarantor->application?->reference ?: '—') }} {{ ucfirst(str_replace('_', ' ', $guarantor->status)) }} {{ $guarantor->relationship ?: '—' }} @php $links = array_filter([ $guarantor->kycImageUrl($guarantor->photo_path) ? ['label' => 'Photo', 'url' => $guarantor->kycImageUrl($guarantor->photo_path)] : null, $guarantor->kycImageUrl($guarantor->id_front_photo_path) ? ['label' => 'ID front', 'url' => $guarantor->kycImageUrl($guarantor->id_front_photo_path)] : null, $guarantor->kycImageUrl($guarantor->id_back_photo_path) ? ['label' => 'ID back', 'url' => $guarantor->kycImageUrl($guarantor->id_back_photo_path)] : null, ]); @endphp @forelse ($links as $link) @php $kycUrl = $link['url']; $kycLabel = $link['label']; @endphp {{ $kycLabel }} @empty — @endforelse
None

Guaranteeing

@forelse (($guaranteesProvidedByClient ?? collect()) as $guarantor) @empty @endforelse
Borrower Loan Status Helpfulness
@if ($guarantor->borrowerClient) {{ $guarantor->borrowerClient->full_name }} @else — @endif {{ $guarantor->loan?->loan_number ?: '—' }} {{ ucfirst(str_replace('_', ' ', $guarantor->status)) }} {{ $guarantor->helpfulness_status ? ucfirst(str_replace('_', ' ', $guarantor->helpfulness_status)) : '—' }}
None
@endif @if ($fragmentTab === 'spouse')

Spouse

@if (auth()->user()?->hasLoanPermission('clients.update')) {{ $loan_client->hasSpouseProfile() ? 'Edit spouse' : 'Add spouse' }} @endif
@if ($loan_client->hasSpouseProfile())
Name Phone ID number
{{ $loan_client->spouse_name }} @if ($loan_client->spouse_phone) @else — @endif {{ $loan_client->spouse_id_number ?: '—' }}
@else
No spouse details captured for this client yet.
@endif

Loan consent history

@forelse (($spouseConsentRecords ?? collect()) as $consentApplication) @php $consentMeta = (array) ($consentApplication->form_meta ?? []); $signedAt = data_get($consentMeta, 'spouse_signed_at'); $otpVerifiedAt = data_get($consentMeta, 'spouse_phone_otp_verified_at'); @endphp @empty @endforelse
Application Product Stage Signed at Phone verified Details
{{ $consentApplication->reference ?: ('APP-#'.$consentApplication->id) }} {{ $consentApplication->product_name ?: '—' }} {{ ucfirst(str_replace('_', ' ', (string) $consentApplication->stage)) }} {{ $signedAt ? \Illuminate\Support\Carbon::parse($signedAt)->format('d M Y H:i') : '—' }} {{ $otpVerifiedAt ? \Illuminate\Support\Carbon::parse($otpVerifiedAt)->format('d M Y H:i') : '—' }} Open
No spouse consent captured on applications yet.
@endif @if ($fragmentTab === 'notes')

Notes

@if (\App\Support\Loan\ClientInteractionPolicy::canLog(auth()->user()) && \Illuminate\Support\Facades\Route::has('loan.clients.interactions.for_client.create')) Log interaction @endif
@forelse (($loan_client->interactions ?? collect()) as $interaction) @php $when = optional($interaction->interacted_at)->format('M j, Y g:i A') ?? optional($interaction->created_at)->format('M j, Y g:i A') ?? '—'; $action = ucfirst(str_replace('_', ' ', (string) ($interaction->interaction_type ?? 'note'))); $body = $interaction->notes ?: 'No additional note.'; @endphp @empty @endforelse
Type Subject Note By When
{{ $action }} {{ filled($interaction->subject) ? $interaction->subject : '—' }} {{ $body }} {{ $interaction->user?->name ?? 'System' }} {{ $when }}
None
@include('loan.clients.partials.client-communication-timeline', [ 'communicationTimeline' => $communicationTimeline ?? [], 'loan_client' => $loan_client, ])
@endif @if ($fragmentTab === 'statement_analysis') @include('loan.clients.partials.entity360-statement-analysis') @endif @if ($fragmentTab === 'wallet')
@include('loan.clients.partials.client-tab-wallet')
@endif @if ($fragmentTab === 'referrals')
@include('loan.clients.partials.referral-panel', [ 'loan_client' => $loan_client, 'referral' => $inboundReferral ?? null, 'outboundReferrals' => $outboundReferrals ?? collect(), 'rewardAmount' => $referralRewardAmount ?? null, ])
@endif @endif
@else @foreach (($entity360['tabs'] ?? []) as $tab) @php $tabId = (string) ($tab['id'] ?? ''); $isInitial = $tabId !== '' && $tabId === ($entity360['initial_tab'] ?? 'loans'); @endphp @if ($tabId !== '')
@if ($isInitial) @include('loan.clients.partials.entity360-tab-fragment', [ 'entity360Fragment' => true, 'entity360FragmentTab' => $tabId, 'e360PanelFragmentTab' => $tabId, ]) @else @endif
@endif @endforeach @endif