Rapport-Laravel/resources/views/titanshcpgatheringreport/report.blade.php

349 lines
14 KiB
PHP

@extends('layouts.vertical-individual', ['page_title' => $title ?? 'Titans HCP Gathering Report'])
@section('css')
<style>
body .account-pages > .container {
max-width: 100%;
padding-left: 0;
padding-right: 0;
}
.titans-hcp-report-page .row {
--bs-gutter-x: 0;
margin-left: 0;
margin-right: 0;
}
.titans-hcp-report-page .card {
border-left: 0;
border-right: 0;
border-radius: 0;
margin-bottom: 0;
}
.titans-hcp-report-page .card-body {
padding-left: 0;
padding-right: 0;
}
.titans-hcp-report-page .page-header {
padding-left: 12px;
padding-right: 12px;
}
.titans-hcp-report-table th,
.titans-hcp-report-table td {
white-space: nowrap;
vertical-align: middle;
border: 1px solid #dee2e6;
font-size: 12px;
}
.titans-hcp-report-table thead th {
text-align: center;
background: #f8f9fa;
}
.titans-hcp-report-table thead .filter-row th {
padding: 4px;
background: #fff;
font-weight: normal;
}
.titans-hcp-report-table thead .filter-row input,
.titans-hcp-report-table thead .filter-row select {
width: 100%;
min-width: 80px;
font-size: 11px;
padding: 2px 6px;
border: 1px solid #ced4da;
border-radius: 3px;
background: #fff;
}
.titans-hcp-report-scroll {
overflow-x: auto;
container-type: inline-size;
}
.titans-hcp-report-table .frozen-col {
position: sticky;
left: 0;
z-index: 2;
background: #fff;
min-width: 120px;
max-width: min(50cqw, 50vw);
overflow: hidden;
text-overflow: ellipsis;
}
.titans-hcp-report-table thead .frozen-col {
z-index: 3;
background: #f8f9fa;
}
.titans-hcp-report-table thead .filter-row .frozen-col {
background: #fff;
}
</style>
@endsection
@section('content')
@php
$uiColumns = [
['key' => 'tm_name', 'label' => 'TM Name'],
['key' => 'hcp_name', 'label' => 'HCP NAME', 'frozen' => true],
['key' => 'legacy_code', 'label' => 'LEGACY_CODE'],
['key' => 'pcode', 'label' => 'PCODE'],
['key' => 'agreement_no', 'label' => 'AgreementNo'],
['key' => 'status', 'label' => 'Status'],
['key' => 'eas_id', 'label' => 'EAS ID'],
['key' => 'activity_report_status', 'label' => 'Activity Report Status'],
['key' => 'payment_status', 'label' => 'Payment Status'],
['key' => 'closure_done', 'label' => 'Closure Done'],
['key' => 'closure_approved', 'label' => 'Closure Approved'],
['key' => 'tm_visit', 'label' => $tm_visit_label],
];
$colCount = count($uiColumns);
@endphp
<div class="titans-hcp-report-page">
<div class="row mb-3 page-header align-items-end">
<div class="col-md-6">
<h4 class="page-title">{{ $title }}</h4>
<p class="text-muted mb-0">Report month: {{ $month }}</p>
</div>
<div class="col-md-6 d-flex justify-content-end align-items-center gap-2">
@if (!empty($months))
<form method="get" action="{{ $base_url }}/report" class="d-flex align-items-center gap-2">
<input type="hidden" name="token" value="{{ $token }}">
<select name="month" class="form-select form-select-sm" style="width: auto;" onchange="this.form.submit()">
@foreach ($months as $availableMonth)
<option value="{{ $availableMonth }}" @selected($availableMonth === $month)>{{ $availableMonth }}</option>
@endforeach
</select>
</form>
@endif
<a href="{{ $base_url }}/export?token={{ urlencode($token) }}&month={{ urlencode($month) }}" class="btn btn-dark btn-sm">
Export
</a>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body titans-hcp-report-scroll">
<table class="table table-sm table-bordered titans-hcp-report-table mb-0" id="titans-hcp-report-table">
<thead>
<tr>
@foreach ($uiColumns as $col)
<th @if (!empty($col['frozen'])) class="frozen-col" @endif>{{ $col['label'] }}</th>
@endforeach
</tr>
<tr class="filter-row">
@foreach ($uiColumns as $index => $col)
<th @if (!empty($col['frozen'])) class="frozen-col" @endif>
<input type="search"
class="titans-hcp-col-filter"
data-col="{{ $index }}"
data-filter-mode="contains"
placeholder="Filter..."
aria-label="Filter {{ $col['label'] }}">
</th>
@endforeach
</tr>
</thead>
<tbody>
@forelse ($rows as $row)
<tr>
<td>{{ $row->tm_name }}</td>
<td class="frozen-col">{{ $row->hcp_name }}</td>
<td>{{ $row->legacy_code }}</td>
<td>{{ $row->pcode }}</td>
<td>{{ $row->agreement_no }}</td>
<td>{{ $row->status }}</td>
<td>{{ $row->eas_id }}</td>
<td>{{ $row->activity_report_status }}</td>
<td>{{ $row->payment_status }}</td>
<td>{{ $row->closure_done }}</td>
<td>{{ $row->closure_approved }}</td>
<td>{{ $row->tm_visit }}</td>
</tr>
@empty
<tr class="titans-hcp-empty-row">
<td colspan="{{ $colCount }}" class="text-center text-muted">No data found for this month.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
@endsection
@section('script-bottom')
<script>
(function () {
var DROPDOWN_MAX_UNIQUE = 10;
var table = document.getElementById('titans-hcp-report-table');
if (!table) {
return;
}
var tbody = table.tBodies[0];
var filterRow = table.querySelector('thead .filter-row');
if (!tbody || !filterRow) {
return;
}
function isDataRow(row) {
return !row.classList.contains('titans-hcp-empty-row')
&& !row.classList.contains('titans-hcp-no-match');
}
function getDataRows() {
return Array.prototype.filter.call(tbody.querySelectorAll('tr'), isDataRow);
}
function uniqueColumnValues(colIndex) {
var seen = {};
var values = [];
getDataRows().forEach(function (row) {
var cell = row.cells[colIndex];
var text = cell ? String(cell.textContent || '').trim() : '';
if (!Object.prototype.hasOwnProperty.call(seen, text)) {
seen[text] = true;
values.push(text);
}
});
values.sort(function (a, b) {
return a.localeCompare(b, undefined, { sensitivity: 'base', numeric: true });
});
return values;
}
function bindFilter(el) {
if (el.tagName === 'SELECT') {
el.addEventListener('change', applyFilters);
} else {
el.addEventListener('input', applyFilters);
el.addEventListener('search', applyFilters);
}
}
function convertLowCardinalityFilters() {
var cells = filterRow.querySelectorAll('th');
Array.prototype.forEach.call(cells, function (th, colIndex) {
var input = th.querySelector('.titans-hcp-col-filter');
if (!input || input.tagName === 'SELECT') {
return;
}
var values = uniqueColumnValues(colIndex);
var hasBlank = values.indexOf('') !== -1;
// Skip dropdown when column has any blank cells, or too many / no values.
if (hasBlank || values.length === 0 || values.length > DROPDOWN_MAX_UNIQUE) {
return;
}
var select = document.createElement('select');
select.className = 'titans-hcp-col-filter';
select.setAttribute('data-col', String(colIndex));
select.setAttribute('data-filter-mode', 'exact');
select.setAttribute('aria-label', input.getAttribute('aria-label') || ('Filter column ' + colIndex));
var allOption = document.createElement('option');
allOption.value = '';
allOption.textContent = 'All';
select.appendChild(allOption);
values.forEach(function (value) {
var option = document.createElement('option');
option.value = value;
option.textContent = value;
select.appendChild(option);
});
th.replaceChild(select, input);
bindFilter(select);
});
}
function getFilters() {
return filterRow.querySelectorAll('.titans-hcp-col-filter');
}
function applyFilters() {
var filters = getFilters();
var filterStates = Array.prototype.map.call(filters, function (el) {
var raw = String(el.value || '');
var mode = el.getAttribute('data-filter-mode') || 'contains';
var isActive = el.tagName === 'SELECT'
? el.selectedIndex > 0
: raw.trim() !== '';
var value = raw.trim().toLowerCase();
if (mode === 'exact' && raw === '__BLANK__') {
value = '';
}
return {
active: isActive,
mode: mode,
value: value
};
});
var rows = tbody.querySelectorAll('tr');
var visibleCount = 0;
Array.prototype.forEach.call(rows, function (row) {
if (!isDataRow(row)) {
return;
}
var cells = row.cells;
var match = true;
for (var i = 0; i < filterStates.length; i++) {
var state = filterStates[i];
if (!state.active) {
continue;
}
var cellText = cells[i] ? String(cells[i].textContent || '').trim().toLowerCase() : '';
if (state.mode === 'exact') {
if (cellText !== state.value) {
match = false;
break;
}
} else if (cellText.indexOf(state.value) === -1) {
match = false;
break;
}
}
row.style.display = match ? '' : 'none';
if (match) {
visibleCount++;
}
});
var noMatchRow = tbody.querySelector('.titans-hcp-no-match');
if (visibleCount === 0 && getDataRows().length) {
if (!noMatchRow) {
noMatchRow = document.createElement('tr');
noMatchRow.className = 'titans-hcp-no-match';
noMatchRow.innerHTML = '<td colspan="{{ $colCount }}" class="text-center text-muted">No rows match the current filters.</td>';
tbody.appendChild(noMatchRow);
}
noMatchRow.style.display = '';
} else if (noMatchRow) {
noMatchRow.style.display = 'none';
}
}
convertLowCardinalityFilters();
Array.prototype.forEach.call(getFilters(), bindFilter);
})();
</script>
@endsection