331 lines
14 KiB
PHP
331 lines
14 KiB
PHP
@extends('layouts.vertical-individual', ['page_title' => $title ?? 'Ciphaler / SB Units Report'])
|
|
|
|
@section('css')
|
|
<style>
|
|
body .account-pages > .container {
|
|
max-width: 100%;
|
|
padding-left: 0;
|
|
padding-right: 0;
|
|
}
|
|
|
|
.team2-units-report-page .row {
|
|
--bs-gutter-x: 0;
|
|
margin-left: 0;
|
|
margin-right: 0;
|
|
}
|
|
|
|
.team2-units-report-page .card {
|
|
border-left: 0;
|
|
border-right: 0;
|
|
border-radius: 0;
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.team2-units-report-page .card-body {
|
|
padding-left: 0;
|
|
padding-right: 0;
|
|
}
|
|
|
|
.team2-units-report-page .page-header {
|
|
padding-left: 12px;
|
|
padding-right: 12px;
|
|
}
|
|
|
|
.team2-units-report-table th,
|
|
.team2-units-report-table td {
|
|
white-space: nowrap;
|
|
vertical-align: middle;
|
|
border: 1px solid #dee2e6;
|
|
}
|
|
|
|
.team2-units-report-table thead th {
|
|
text-align: center;
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
.team2-units-report-table .doctor-col {
|
|
position: sticky;
|
|
left: 0;
|
|
z-index: 2;
|
|
background: #fff;
|
|
min-width: 220px;
|
|
}
|
|
|
|
.team2-units-report-table .meta-col {
|
|
min-width: 120px;
|
|
}
|
|
|
|
.team2-units-report-table thead .doctor-col {
|
|
z-index: 3;
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
.team2-units-report-scroll {
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.team2-units-report-pagination {
|
|
padding: 12px 16px;
|
|
border-top: 1px solid #dee2e6;
|
|
background: #fff;
|
|
position: sticky;
|
|
bottom: 0;
|
|
z-index: 5;
|
|
}
|
|
|
|
.team2-units-report-pagination-top {
|
|
border-top: 0;
|
|
border-bottom: 1px solid #dee2e6;
|
|
}
|
|
|
|
.team2-units-report-pagination .pagination {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
#team2-units-report-loader {
|
|
align-items: center;
|
|
background: rgba(255, 255, 255, 0.85);
|
|
display: none;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
height: 100%;
|
|
justify-content: center;
|
|
left: 0;
|
|
position: fixed;
|
|
top: 0;
|
|
width: 100%;
|
|
z-index: 9999;
|
|
}
|
|
|
|
#team2-units-report-loader.is-visible {
|
|
display: flex;
|
|
}
|
|
|
|
#team2-units-report-loader img {
|
|
height: 64px;
|
|
width: 64px;
|
|
}
|
|
</style>
|
|
@endsection
|
|
|
|
@section('content')
|
|
@php
|
|
$pagination = $pagination ?? (object) ['page' => 1, 'per_page' => 50, 'total' => 0, 'total_pages' => 0];
|
|
$currentPage = (int) ($pagination->page ?? 1);
|
|
$totalPages = (int) ($pagination->total_pages ?? 0);
|
|
$perPage = (int) ($perPage ?? $pagination->per_page ?? 50);
|
|
$totalDoctors = (int) ($pagination->total ?? 0);
|
|
$search = trim((string) ($search ?? ''));
|
|
$type = $type ?? 'ciphaler';
|
|
$pageQuery = http_build_query(array_filter([
|
|
'type' => $type,
|
|
'per_page' => $perPage,
|
|
'search' => $search !== '' ? $search : null,
|
|
'token' => !empty($token ?? '') ? $token : null,
|
|
], fn ($value) => $value !== null && $value !== ''));
|
|
$pageBase = $base_url . '/report?' . $pageQuery;
|
|
$metaColumnCount = 3;
|
|
@endphp
|
|
<div id="team2-units-report-loader" class="is-visible" aria-live="polite" aria-busy="true">
|
|
<img src="/images/loader-large.gif" alt="">
|
|
<span class="text-muted">Loading report...</span>
|
|
</div>
|
|
<div class="team2-units-report-page">
|
|
<div class="row mb-3 page-header">
|
|
<div class="col-md-6">
|
|
<h4 class="page-title">{{ $title }}</h4>
|
|
<p class="text-muted mb-0">
|
|
Doctor units from April 2026 through the current month.
|
|
Showing {{ $typeLabel ?? strtoupper($type) }} metrics
|
|
({{ collect($metrics)->pluck('label')->implode(', ') }}).
|
|
Cells after April are colored vs the previous month:
|
|
<span class="badge bg-success">up</span>
|
|
<span class="badge bg-danger">down</span>.
|
|
</p>
|
|
@if ($totalDoctors > 0)
|
|
<p class="text-muted mb-0 small">
|
|
Showing {{ count($doctors) }} of {{ number_format($totalDoctors) }} doctors
|
|
(page {{ $currentPage }} of {{ max($totalPages, 1) }})
|
|
@if ($search !== '')
|
|
matching "{{ $search }}"
|
|
@endif
|
|
</p>
|
|
@elseif ($search !== '')
|
|
<p class="text-muted mb-0 small">No doctors found matching "{{ $search }}".</p>
|
|
@endif
|
|
</div>
|
|
<div class="col-md-6 d-flex justify-content-end align-items-center gap-2 flex-wrap">
|
|
<form method="get" action="{{ $base_url }}/report" id="team2-search-form" class="d-flex align-items-center gap-2 team2-units-report-nav-form">
|
|
<input type="hidden" name="page" value="1">
|
|
<input type="hidden" name="type" value="{{ $type }}">
|
|
<input type="hidden" name="per_page" value="{{ $perPage }}">
|
|
@if (!empty($token ?? ''))
|
|
<input type="hidden" name="token" value="{{ $token }}">
|
|
@endif
|
|
<label for="team2-report-search" class="form-label mb-0 small text-muted">Search</label>
|
|
<input type="search" name="search" id="team2-report-search" class="form-control form-control-sm" style="width: 220px;" value="{{ $search }}" placeholder="Doctor, MSL, user, zone...">
|
|
<button type="submit" class="btn btn-outline-secondary btn-sm">Apply</button>
|
|
@if ($search !== '')
|
|
<a href="{{ $base_url }}/report?{{ http_build_query(array_filter(['type' => $type, 'per_page' => $perPage, 'token' => !empty($token ?? '') ? $token : null])) }}" class="btn btn-link btn-sm text-decoration-none">Clear</a>
|
|
@endif
|
|
</form>
|
|
<form method="get" action="{{ $base_url }}/report" id="team2-per-page-form" class="d-flex align-items-center gap-2 team2-units-report-nav-form">
|
|
<input type="hidden" name="page" value="1">
|
|
<input type="hidden" name="type" value="{{ $type }}">
|
|
@if (!empty($token ?? ''))
|
|
<input type="hidden" name="token" value="{{ $token }}">
|
|
@endif
|
|
@if ($search !== '')
|
|
<input type="hidden" name="search" value="{{ $search }}">
|
|
@endif
|
|
<label for="per_page" class="form-label mb-0 small text-muted">Per page</label>
|
|
<select name="per_page" id="per_page" class="form-select form-select-sm" style="width: auto;" onchange="this.form.submit()">
|
|
@foreach ([25, 50, 100, 200] as $size)
|
|
<option value="{{ $size }}"@if($perPage === $size) selected @endif>{{ $size }}</option>
|
|
@endforeach
|
|
</select>
|
|
</form>
|
|
<a href="{{ $base_url }}/export?{{ http_build_query(array_filter(['type' => $type, 'search' => $search !== '' ? $search : null, 'token' => !empty($token ?? '') ? $token : null])) }}" class="btn btn-dark btn-sm">
|
|
Export All
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
@include('team2unitsreport._pagination', ['paginationPosition' => 'team2-units-report-pagination-top'])
|
|
<div class="card-body team2-units-report-scroll">
|
|
<table class="table table-sm table-bordered team2-units-report-table mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th class="doctor-col" rowspan="2">Doctor Name</th>
|
|
<th class="meta-col" rowspan="2">MSL Code</th>
|
|
<th class="meta-col" rowspan="2">User</th>
|
|
@foreach ($months as $month)
|
|
<th colspan="{{ count($metrics) }}">{{ $month->label ?? $month->key }}</th>
|
|
@endforeach
|
|
</tr>
|
|
<tr>
|
|
@foreach ($months as $month)
|
|
@foreach ($metrics as $metric)
|
|
<th>{{ $metric->label ?? $metric->id }}</th>
|
|
@endforeach
|
|
@endforeach
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse ($doctors as $doctor)
|
|
<tr>
|
|
<td class="doctor-col">{{ $doctor->name }}</td>
|
|
<td class="meta-col">{{ $doctor->msl_code ?? '-' }}</td>
|
|
<td class="meta-col">{{ $doctor->user ?? '-' }}</td>
|
|
@foreach ($months as $monthIndex => $month)
|
|
@php
|
|
$monthKey = $month->key ?? '';
|
|
$doctorData = $data->{$doctor->id} ?? null;
|
|
$monthData = is_object($doctorData) ? ($doctorData->{$monthKey} ?? null) : null;
|
|
$prevMonthKey = $monthIndex > 0 ? ($months[$monthIndex - 1]->key ?? '') : '';
|
|
$prevMonthData = ($prevMonthKey !== '' && is_object($doctorData))
|
|
? ($doctorData->{$prevMonthKey} ?? null)
|
|
: null;
|
|
@endphp
|
|
@foreach ($metrics as $metric)
|
|
@php
|
|
$metricId = $metric->id ?? '';
|
|
$value = is_object($monthData) ? ($monthData->{$metricId} ?? null) : null;
|
|
$cellClass = 'text-center';
|
|
if ($monthIndex > 0 && $value !== null && $value !== '' && is_numeric($value)) {
|
|
$prevValue = is_object($prevMonthData) ? ($prevMonthData->{$metricId} ?? null) : null;
|
|
if ($prevValue !== null && $prevValue !== '' && is_numeric($prevValue)) {
|
|
$currentNum = (float) $value;
|
|
$prevNum = (float) $prevValue;
|
|
if ($currentNum > $prevNum) {
|
|
$cellClass .= ' table-success';
|
|
} elseif ($currentNum < $prevNum) {
|
|
$cellClass .= ' table-danger';
|
|
}
|
|
}
|
|
}
|
|
@endphp
|
|
<td class="{{ $cellClass }}">{{ $value !== null && $value !== '' ? $value : '-' }}</td>
|
|
@endforeach
|
|
@endforeach
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="{{ $metaColumnCount + (count($months) * max(count($metrics), 1)) }}" class="text-center text-muted">
|
|
@if ($search !== '')
|
|
No doctors found matching "{{ $search }}".
|
|
@else
|
|
No doctor data found.
|
|
@endif
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@include('team2unitsreport._pagination')
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@section('script-bottom')
|
|
<script>
|
|
(function () {
|
|
var loader = document.getElementById('team2-units-report-loader');
|
|
if (!loader) {
|
|
return;
|
|
}
|
|
|
|
function hideLoader() {
|
|
loader.classList.remove('is-visible');
|
|
loader.setAttribute('aria-busy', 'false');
|
|
}
|
|
|
|
function showLoader() {
|
|
loader.classList.add('is-visible');
|
|
loader.setAttribute('aria-busy', 'true');
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', hideLoader, { once: true });
|
|
} else {
|
|
hideLoader();
|
|
}
|
|
|
|
window.addEventListener('pageshow', function (event) {
|
|
if (event.persisted) {
|
|
hideLoader();
|
|
}
|
|
});
|
|
|
|
document.addEventListener('click', function (event) {
|
|
var link = event.target.closest('.team2-units-report-pagination a.page-link[href]:not([href="#"])');
|
|
if (link) {
|
|
showLoader();
|
|
}
|
|
});
|
|
|
|
var searchForm = document.getElementById('team2-search-form');
|
|
if (searchForm) {
|
|
searchForm.addEventListener('submit', function () {
|
|
showLoader();
|
|
});
|
|
}
|
|
|
|
var perPageForm = document.getElementById('team2-per-page-form');
|
|
if (perPageForm) {
|
|
perPageForm.addEventListener('change', function (event) {
|
|
if (event.target && event.target.name === 'per_page') {
|
|
showLoader();
|
|
}
|
|
});
|
|
}
|
|
})();
|
|
</script>
|
|
@endsection
|