@extends('layout.app') @php use Carbon\Carbon; @endphp {{-- Critical: hide cx-overlay modals in to prevent FOUC on page load --}} @push('styles') @endpush @section('content') @php $r = $list->first(); // Reseller name + type (resolved from reseller_id) $resellerName = $r->reseller_name ?? null; $isOwnReseller = $r->reseller_type === 'own'; $isClosed = !empty($r->deleted_at); // Address line $addressParts = array_filter([ $r->flat_no ?? null, $r && $r->road_no ? 'Road ' . $r->road_no : null, $r->building_name ?? null, $r->block_sector ?? null, checkSettings('area') == 'enable' ? $r->area ?? null : null, ]); $addressLine = count($addressParts) ? implode(', ', $addressParts) : ''; // Google-map link from stored lat/long $mapLink = $r && $r->client_latitude && $r->client_longitude ? 'https://maps.google.com/?q=' . $r->client_latitude . ',' . $r->client_longitude : null; // Balance: customer_accounts.dueAmount ( > 0 => Due, < 0 => Advance ) $due = (float) ($r->dueAmount ?? 0); // Expiry + days remaining $expDate = $r && $r->expire_date ? Carbon::parse($r->expire_date) : null; $daysLeft = $expDate ? Carbon::today()->diffInDays($expDate->copy()->startOfDay(), false) : null; // Status badge mapping (clients_status: active | expired | deactive | disable) $statusMap = [ 'active' => ['hero' => 'cx-sb-active', 'tag' => 'cx-tag-active', 'label' => 'Active'], 'expired' => ['hero' => 'cx-sb-expired', 'tag' => 'cx-tag-expired', 'label' => 'Expired'], 'deactive' => ['hero' => 'cx-sb-deact', 'tag' => 'cx-tag-deact', 'label' => 'Deactivated'], 'disable' => ['hero' => 'cx-sb-closed', 'tag' => 'cx-tag-closed', 'label' => 'Disabled'], ]; $st = $statusMap[$r->clients_status ?? ''] ?? [ 'hero' => 'cx-sb-closed', 'tag' => 'cx-tag-closed', 'label' => ucfirst($r->clients_status ?? ''), ]; // Seed values only — the live status is fetched by cxLoadLiveInfo() after // render, which replaces the connection bar, buttons and session details. // isLive, not activeClientInfo — the latter also carries the last known // session for an offline client, which would read as online here. $isOnline = empty($error) && !empty($isLive); $onlineIp = $activeClientInfo['address'] ?? ($r->ip_address ?? null); // Contact number normalised for tel/sms/whatsapp links $contact = $r->contact_no ?? ''; $contactDigits = preg_replace('/\D+/', '', $contact); $waNumber = $contactDigits ? (substr($contactDigits, 0, 2) === '88' ? $contactDigits : '88' . $contactDigits) : ''; @endphp
{{-- ══════════════════ HERO ══════════════════ --}}
{{ strtoupper(substr($r->clients_name ?? 'U', 0, 1)) }}

{{ $r->clients_name ?? '' }}

{{ $st['label'] }}
{{ $r->userid ?? '' }} @can('show-mother-package') Package - {{ $r->package_name ?? '' }} @endcan Pop - {{ $r->popname ?? '' }} Exp. Date - {{ $expDate ? $expDate->format('d M Y') : 'N/A' }} Reseller - {{ $resellerName ?? 'N/A' }}
Call @can('single-customer-sms-send') @endcan WhatsApp @if ($mapLink) View on Map @endif @if (!$isClosed) @if ($isOwnReseller) @can('money-receipt-entry') @endcan @else @can('customer-recharge') @if (($r->client_approval ?? '') == 'approved') @endif @endcan @endif @endif {{-- ONU power, up here where it is seen without scrolling. Reads the same value as the ONU Information card below; the two are kept in step by the refresh handler, which writes both. A click jumps to the power history graph, but only when there is a graph to jump to: onu_info_log off means onu_info_logs is never written, and show-connection-information is what renders the card at all. Without both it stays a plain reading. --}} @if (globalPermission('onu_information_laser')) @can('onu_information_laser') @isset($onuInfo->laser) @if (globalPermission('onu_info_log') && auth()->user()->can('show-connection-information')) ONU Power: {{ $onuInfo->laser }} @else ONU Power: {{ $onuInfo->laser }} @endif @endisset @endcan @endif
{{-- ══════════════════ QUICK ACTIONS BAR ══════════════════ --}} @if (!$isClosed)
@if ($isOwnReseller) @can('money-receipt-entry') @endcan @else @can('customer-recharge') @if (($r->client_approval ?? '') == 'approved') @endif @endcan @endif @if ($isOwnReseller) @endif @if (checkSettings('show-traffice') == 'enable' && ($r->client_approval ?? '') != 'pending') @endif @if ($isOwnReseller) @can('money-receipt-entry') @endcan @else @if (auth()->user()->can('reseller-balance-log-report') || auth()->user()->can('sub-reseller-balance-log-report')) @endif @endif @can('single-customer-sms-send') @endcan {{-- Others dropdown --}}
@if ($isOwnReseller) @php $paymentLink = App\Http\Controllers\CompanyInfoController::baseUrl() . $r->slug; @endphp

{{ $paymentLink }}

Print QR Code @endif
@can('changeBillCycle') @if ($r->is_free == 0) @endif @endcan @can('change-expire-date') @endcan @can('extend-temporary-dedline') @if ($isOwnReseller) @endif @endcan @can('change_auto_deactive_date') @endcan @can('changePackage') @endcan
@if ($r->clients_status != 'disable') @can('id-disable') @endcan @endif @if ($r->clients_status != 'deactive') @can('customer-deactivated') @endcan @endif
@else {{-- Closed client: show read-only history buttons only --}}
@if ($isOwnReseller) @can('money-receipt-entry') @endcan @else @if (auth()->user()->can('reseller-balance-log-report') || auth()->user()->can('sub-reseller-balance-log-report')) @endif @endif
@endif {{-- ══════════════════ THREE-COLUMN GRID ══════════════════ --}}
@can('show-service-information') {{-- CARD 1 · CUSTOMER INFORMATION --}}
Customer Information
CID {{ $r->id ?? '' }}
@if (!$r->isStatic)
Username {{ $r->userid ?? '' }}
@else
IP Address {{ $r->ip_address ?? '' }} @if (!empty($r->ip_address)) @endif
@endif @if (checkSettings('customer_code') == 'enable')
Customer Code {{ $r->customer_code ?? '' }}
@endif @if (!$r->isStatic)
Password •••••
@endif
Contact {{ $contact }} @if (!$isClosed)
@can('single-customer-sms-send') @endcan
@endif
@can('show-address-information')
Address {{ $addressLine }} @if ($mapLink)
@endif
Area {{-- $r is a joined stdClass (DB::table), so clientsinfo.area is flat on $r --}} {{ $r->area ?? 'N/A' }}
@endcan
Reseller {{ $resellerName ?? 'N/A' }}
POP Name {{ $r->popname ?? '' }} @if (!$isClosed) @can('pop_change_on_client_edit')
@endcan @endif
Billing Date {{ $r->billing_cycle ?? '' }} of month
@if ($isOwnReseller)
Balance @if ($due > 0) {{ number_format($due, 2) }} BDT (Due) @elseif ($due < 0) {{ number_format(abs($due), 2) }} BDT (Advance) @else 0.00 BDT @endif @if (!$isClosed)
@if ($isOwnReseller) @can('money-receipt-entry') @endcan @else @can('customer-recharge') @if (($r->client_approval ?? '') == 'approved') @endif @endcan @endif @can('add_other_bill') @if ($isOwnReseller) @endif @endcan
@endif
@endif
Package @if ($r->sub_package_name && $r->subreseller == 'yes') @can('show-sub-package') {{ $r->sub_package_name }} @endcan @else @can('show-mother-package') {{ $r->package_name ?? '' }} @endcan @endif @if (!$isClosed) @can('changePackage')
@endcan @endif
Expiry Date {{ $expDate ? $expDate->format('Y-m-d') : '' }} @if (!is_null($daysLeft)) @if ($daysLeft > 7) {{ $daysLeft }}d left @elseif ($daysLeft >= 0) {{ $daysLeft }}d left @else {{ abs($daysLeft) }}d overdue @endif @endif @if (!$isClosed) @can('change-expire-date')
@endcan @endif
Extended {{ $r->payment_dadeline ?? '0' }} days @if (!$isClosed) @can('extend-temporary-dedline') @if ($isOwnReseller)
@endif @endcan @endif
Status {{ $st['label'] }}
@endcan @can('show-connection-information') {{-- CARD 2 · CONNECTION STATUS --}}
Connection Status @if ($r->ignoreMKCheck == 0) @else @endif
@php $mkIp = optional(optional($clientUser->pop)->nas)->nasname; @endphp @if ($mkIp)
MikroTik: {{ $mkIp }}
@endif
{{ $isOnline ? 'Online' : 'Offline' }} @if ($isOnline && $onlineIp) {{ $onlineIp }} @else @endif
@can('onlineUserDisconnection') @endcan
Perm. Discount {{ number_format((float) ($r->parmanent_discount ?? 0), 2) }} BDT @if (!$isClosed && checkSettings('parmanent-discount') == 'enable' && $isOwnReseller) @if (auth()->user()->can('parmanent-discount'))
@endif @endif
@if (checkSettings('free_client') == 'enable')
Free Client @if (!empty($r->is_free)) Yes @else No @endif @if (!$isClosed) @can('add-free-client')
@endcan @endif
@endif @if (checkSettings('single_client_billing_type') == 'enable')
Billing Type {{ $r->billing_type ? ucfirst($r->billing_type) : 'N/A' }} @if (!$isClosed && auth()->user()->can('single_client_billing_type'))
@endif
@endif @if (!$isClosed)
{{-- Both states render; cxLoadLiveInfo() shows whichever matches the live status. --}}
Remote Login
@endif
@endcan @can('show-personal-information') {{-- CARD 3 · OTHER DETAILS --}}
Other Details
NID {{ $r->national_id ?? '' }} @if (!empty($r->national_id)) @endif
Father Name{{ $r->father_name ?? '' }}
Date of Birth{{ $r->dob ?? null ? date('d-M-Y', strtotime($r->dob)) : '' }}
Remote User {{ $r->remote_access_username ?? '' }} @if (!empty($r->remote_access_username)) @endif
Remote Pass {{ $r->remote_access_password ?? '' }} @if (!empty($r->remote_access_password)) @endif
Created{{ $r->created_at ?? null ? date('d-M-Y h:i:s A', strtotime($r->created_at)) : '' }}
Joining Date{{ $r->joinDate ?? null ? date('d-M-Y', strtotime($r->joinDate)) : '' }}
Created By{{ optional(\App\Models\User::find($r->created_by ?? 0))->name ?? '' }}
@if (!auth()->user()->hasRole(['Reseller Admin', 'Sub Reseller', 'Sub Reseller Technician']))
Marketed By{{ $r->marketing_employee_name ?? '' }}
@endif
Referenced By{{ $previousClientReferenceText ?? '' }}
OTC Amount{{ number_format((float) ($r->otc ?? 0), 2) }} BDT
@endcan
{{-- /.cx-grid --}} {{-- ══════════════════ SESSION & ONU ROW ══════════════════ --}} @php // Whether the ONU card will render. It decides how much room is left // for Login Attempts below: with ONU present that card is alone on // its own row and spans both columns, otherwise it fills the empty // cell next to Session Details. $hasOnuCard = globalPermission('onu_information_laser') && auth()->user()->can('onu_information_laser') && isset($onuInfo->laser); @endphp
{{-- SESSION DETAILS --}} @if (checkSettings('show-traffice') == 'enable' && ($r->client_approval ?? '') != 'pending')
Session Details
@php // Seeded from the DB; the live values arrive via cxLoadLiveInfo(). $clientMac = $r->mac ?? null; @endphp
Last Link Up …
Last Logout …
Duration …
Client MAC {{ $clientMac ?? '…' }}
Vendor …
Download
0.00 GB
Upload
0.00 GB
@endif {{-- ONU INFORMATION --}} @if (globalPermission('onu_information_laser')) @can('onu_information_laser') @isset($onuInfo->laser)
ONU Information
@php $onuMac = !empty($onuInfo->mac) ? strtoupper(implode(':', str_split($onuInfo->mac, 2))) : null; @endphp
OLT{{ $onuInfo->oltaddress ?? '-' }} — "{{ $onuInfo->oltName ?? '-' }}"
ONU Id{{ $onuInfo->onuid ?? '-' }}
Power (Laser) {{ $onuInfo->laser ?? '-' }}
Last Update{{ isset($onuInfo->updated_at) ? \Carbon\Carbon::parse($onuInfo->updated_at)->format('d-m-Y h:i A') : '-' }}
PON ID, Vlan{{ $onuInfo->interface ?? '-' }}, {{ $onuInfo->Vlan ?? '-' }}
Device MAC {{ $onuMac ?? '-' }} @if ($onuMac) @endif
@endisset @endcan @endif {{-- RADIUS LOGIN ATTEMPTS --}} {{-- Last in this two-column grid: with no ONU card it fills the cell beside Session Details, and when ONU is present it drops to its own row and spans the full width rather than leaving half of it empty. Filled by cxLoadLoginAttempts() after render, and left hidden on an API-only install, where radpostauth is never written. --}} @can('show-connection-information') @endcan
{{-- /.cx-grid-onu --}} {{-- ══════════════════ ONU POWER HISTORY ══════════════════ --}} {{-- Full width below Login Attempts. Filled by cxLoadOnuPower() after render, and left hidden unless the onu_info_log setting is on — onu_info_logs is only written while it is. --}} @can('show-connection-information') @endcan {{-- ══════════════════ DOCUMENTS ══════════════════ --}} @if (checkSettings('pictureUpload') == 'enable') @if ($r->bill_generate == 'yes' || checkSettings('file_up_for_own_other') == 'enable')
Documents
@php $s3 = checkSettings('store_image_to_s3') == 'enable'; $cxDocs = [ [ 'key' => 'customer_profile_picture', 'label' => 'Profile Picture', 'folder' => 'customer_profile_picture', ], ['key' => 'customer_agrement', 'label' => 'Agreement', 'folder' => 'customer_agrement'], ['key' => 'profilePicture', 'label' => 'Picture', 'folder' => 'profilePicture'], ['key' => 'picture', 'label' => 'Building Photo', 'folder' => 'picture'], ['key' => 'client_door', 'label' => 'Flat Door', 'folder' => 'client_door'], ['key' => 'onu_router_info', 'label' => 'ONU / Router', 'folder' => 'onu_router_info'], ]; if (checkSettings('national_id_picture') == 'enable') { $cxDocs[] = ['key' => 'nid_image', 'label' => 'National ID', 'folder' => 'nationalId']; } @endphp @foreach ($cxDocs as $doc) @php $fileName = $r->{$doc['key']} ?? null; $fileUrl = null; if ($fileName) { $fileUrl = $s3 ? \Illuminate\Support\Facades\Storage::disk('s3')->url( $doc['folder'] . '/' . $fileName, ) : asset('storage/' . $doc['folder'] . '/' . $fileName); } @endphp
{{ $doc['label'] }} {{-- Thumbnail --}} @if ($fileUrl) {{ $doc['label'] }} @else @endif {{-- Hidden file input --}} @if (!$isClosed) @endif
@if (!$isClosed) @if ($fileUrl) @endif @endif @if ($fileUrl) @endif
@endforeach
@endif @endif {{-- ══════════════════ MODALS ══════════════════ --}} {{-- PAYMENT --}}
Record Payment
{{-- CREATE TICKET --}}
Create Support Ticket
{{-- CHANGE PACKAGE --}}
Change Package
@csrf
{{ $r->sub_package_name && $r->subreseller == 'yes' ? $r->sub_package_name : $r->package_name ?? '' }}
{{-- EDIT HISTORY --}}
Edit History {{ $r->userid }}

Loading…

{{-- AUTO DEACTIVE DATE --}} @can('change_auto_deactive_date')
Auto Deactive Date
@csrf
@if ($r->auto_deactive && date('Y', strtotime($r->auto_deactive)) > 1970) {{ date('d-M-Y', strtotime($r->auto_deactive)) }} @else Not set @endif
@endcan {{-- CHANGE STATUS --}}
Change Account Status
@if ($r->deleted_at) @can('customer-reactivate') @endcan @else @canany(['id-enable', 'customer-reactivate']) @endcanany @can('id-disable') @endcan @can('customer-deactivated') @endcan @can('customer-delete') @endcan @endif
{{-- LIVE TRAFFIC --}}
Live Traffic
Username: {{ $r->userid }}
Download
—
Upload
—
Waiting…
{{-- PAYMENT HISTORY --}}
Payment History
Date Amount Method Recorded By
2026-05-12 700 BDT bKash Admin
2026-04-12 700 BDT Cash Karim
2026-03-12 700 BDT Nagad Admin
2026-02-12 1200 BDT Cash Rahim
2026-01-12 700 BDT bKash Admin
{{-- SESSIONS --}}
Session Details
IP Address Started Duration Status
172.0.0.1 2026-06-03 08:14 14h 32m Online
172.0.0.1 2026-06-02 09:00 23h 14m Ended
172.0.0.1 2026-06-01 07:45 22h 50m Ended
{{-- EXPIRE DATE EXTEND --}}
Expire Date Extend
@csrf
Current: {{ $r->payment_dadeline ?? 0 }} days
{{-- CHANGE EXTENDED DATE --}}
Change Extended Date
{{-- ADD BILL --}}
Add Custom Bill
{{-- CHANGE DISCOUNT --}}
Permanent Discount
@csrf
Set 0 to remove discount. Current: {{ number_format((float) ($r->parmanent_discount ?? 0), 2) }} BDT
{{-- FREE CLIENT --}}
Free Client

Current status: {{ !empty($r->is_free) ? 'Free' : 'Paid' }}

{{-- BILLING TYPE --}}
Billing Type

Current: {{ $r->billing_type === 'day_to_day' ? 'Date2Date' : ($r->billing_type === 'monthly' ? 'Monthly' : 'N/A') }}

{{-- BILL CYCLE CHANGE --}} @can('changeBillCycle')
Bill Cycle Change
@csrf
@endcan {{-- EXPIRE DATE CHANGE --}} @can('change-expire-date')
Expire Date Change
@csrf
@endcan {{-- CHANGE POP --}}
Change POP
{{-- CHANGE CONTACT --}}
Change Contact
{{-- PAYMENT LOG --}}
Payment Log
Loading…
{{-- ══════════════════ DOCUMENT PREVIEW MODAL ══════════════════ --}} @push('styles') @endpush {{-- ══════════════════ PING TEST MODAL ══════════════════ --}} @push('styles') @endpush {{-- ══════════════════ SMS MODAL (Bootstrap 4) ══════════════════ --}} @push('styles') @endpush @push('styles') @endpush {{-- ══════════════════ EDIT MODAL ══════════════════ --}} {{-- ══════════════════ CREATE TICKET MODAL ══════════════════ --}} @push('styles') @endpush {{-- ══════════════════ PAY HISTORY MODAL ══════════════════ --}} @push('styles') @endpush {{-- TOAST CONTAINER --}}
{{-- /.cx-page --}} @endsection @section('ajax') @push('styles') @endpush @push('styles') @endpush @if (checkSettings('show-traffice') == 'enable' && ($r->client_approval ?? '') != 'pending') @endif @endsection