@extends('layouts.app') @section('title', __('laboratory::messages.catalogue.title')) @php use App\Modules\Laboratory\Enums\TestCategory; use App\Modules\Laboratory\Models\LabTest; /* | A colour per discipline, so the eye can group a long table without | reading it. Fixed per category rather than assigned in order, because a | filter that reorders the page must not repaint haematology green. | | Every badge carries its name as well as its colour — about one man in | twelve has a colour vision deficiency, and this is a clinical screen. */ $groupPill = static fn (TestCategory $category): string => match ($category) { TestCategory::Haematology => 'px-pill--pink', TestCategory::Chemistry => 'px-pill--blue', TestCategory::Microbiology => 'px-pill--amber', TestCategory::Serology => 'px-pill--violet', TestCategory::Urinalysis => 'px-pill--green', TestCategory::Histopathology => 'px-pill--red', TestCategory::Other => 'px-pill--grey', }; $cards = [ [ 'label' => __('laboratory::messages.catalogue.card_total'), 'value' => $summary['total'], 'icon' => 'bi-clipboard2-pulse-fill', 'tone' => 'violet', 'note' => $summary['added_this_month'] > 0 ? trans_choice('laboratory::messages.catalogue.card_added', $summary['added_this_month'], ['count' => $summary['added_this_month']]) : __('laboratory::messages.catalogue.card_added_none'), ], [ 'label' => __('laboratory::messages.catalogue.card_groups'), 'value' => $summary['groups'], 'icon' => 'bi-folder-fill', 'tone' => 'green', 'note' => __('laboratory::messages.catalogue.card_groups_note'), ], [ 'label' => __('laboratory::messages.catalogue.card_panels'), 'value' => $summary['panels'], 'icon' => 'bi-grid-3x3-gap-fill', 'tone' => 'blue', 'note' => __('laboratory::messages.catalogue.card_panels_note'), ], [ 'label' => __('laboratory::messages.catalogue.card_in_use'), 'value' => $summary['in_use'], 'icon' => 'bi-star-fill', 'tone' => 'amber', 'note' => __('laboratory::messages.catalogue.card_in_use_note'), ], ]; $hasFilters = collect($filters)->filter(fn ($value): bool => $value !== '')->isNotEmpty(); $canAdd = auth()->user()?->can('create', LabTest::class) ?? false; @endphp @section('content') {{-- ── Page head ──────────────────────────────────────────────────────── --}}

{{ __('laboratory::messages.catalogue.title') }}

{{ __('laboratory::messages.catalogue.subtitle') }}

{{ __('laboratory::messages.catalogue.microbiology') }} @if ($canAdd) {{-- Scrolls to the form rather than opening a modal: on a wide screen the form is already beside the table, and a modal over it would hide the list somebody is working from. --}} {{ __('laboratory::messages.catalogue.add_test') }} @endif
{{-- Said once, prominently, on the screen where it matters. The failure mode — trusting a shipped range against a different analyser — is silent, and a silent failure needs a loud warning. --}}
{{ __('laboratory::messages.catalogue.seeded_warning') }}
{{-- ── Summary ────────────────────────────────────────────────────────── --}}
@foreach ($cards as $card)

{{ $card['label'] }}

{{ number_format($card['value']) }}

{{ $card['note'] }}

@endforeach
{{-- ── Filters ────────────────────────────────────────────────── --}} {{-- Outside the swapped region: that region is replaced wholesale on every filter change, which would destroy the field being typed into. --}}
@if ($hasFilters) {{ __('common.reset') }} @endif
{{-- ── Tests ──────────────────────────────────────────────────── --}}

{{ __('laboratory::messages.catalogue.list_title', ['count' => number_format($tests->total())]) }}

@if ($tests->total() > 0)

{{ __('laboratory::messages.catalogue.showing', [ 'from' => number_format($tests->firstItem() ?? 0), 'to' => number_format($tests->lastItem() ?? 0), 'total' => number_format($tests->total()), ]) }}

@endif
@forelse ($tests as $test) @empty @endforelse
{{ __('laboratory::messages.catalogue.code') }} {{ __('laboratory::messages.catalogue.name') }} {{ __('laboratory::messages.catalogue.category') }} {{ __('laboratory::messages.catalogue.unit') }} {{ __('laboratory::messages.catalogue.ranges') }} {{ __('laboratory::messages.catalogue.kind') }} {{ __('common.status') }} {{ __('common.actions') }}
{{ $test->code }} {{ $test->name }} @if ($test->short_name) {{ $test->short_name }} @endif {{ $test->category->label() }} {{ $test->unit ?: '—' }} @if ($test->isPanel()) — @elseif ($test->reference_ranges_count === 0) {{-- A test with no range produces unflagged results, and an unflagged result is one a tired clinician skims past. --}} {{ __('laboratory::messages.catalogue.no_ranges') }} @else {{ trans_choice('laboratory::messages.catalogue.ranges_count', $test->reference_ranges_count, ['count' => $test->reference_ranges_count]) }} @endif {{ $test->isPanel() ? __('laboratory::messages.kind.panel') : __('laboratory::messages.kind.analyte') }} {{-- "Available to order", not "enabled". The word on the screen is the decision the Super Admin makes. --}} {{ $test->is_active ? __('laboratory::messages.catalogue.available') : __('laboratory::messages.catalogue.withdrawn') }} {{-- Deciding a test may be ordered is the Super Admin's alone — see LabTestPolicy::activate. No delete: a test that has ever been reported is evidence, so it is withdrawn instead. --}} @can('activate', $test)
@csrf @method('PATCH')
@endcan

{{ $hasFilters ? __('laboratory::messages.catalogue.empty_filtered') : __('laboratory::messages.catalogue.empty') }}

{{ $hasFilters ? __('laboratory::messages.catalogue.empty_filtered_text') : __('laboratory::messages.catalogue.empty_text') }}

@if ($tests->hasPages())
{{ $tests->links() }}
@endif
{{-- ── Add a test ─────────────────────────────────────────────────── --}} @if ($canAdd) @endif {{-- What those tests are drawn into. Beside the catalogue because it is part of it, and behind the same grant. --}} @include('laboratory::catalogue.partials.containers')
@endsection