Files
lis/htdocs/resources/views/admin/biorepository.blade.php
T
2026-02-21 05:39:38 +07:00

504 lines
23 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@extends('base.layout')
@push('styles')
<style>
.bio-summary-card {
border-left: 4px solid #188ae2;
}
.cabinet-visual {
border: 2px solid #2d3e50;
border-radius: 12px;
background: #f7fbff;
padding: 15px;
margin-bottom: 18px;
}
.rack-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 12px;
}
.rack-box {
border: 1px solid #d7e3ef;
border-radius: 10px;
background: #ffffff;
padding: 12px;
}
.rack-header {
font-weight: 700;
color: #1b3a57;
margin-bottom: 4px;
}
.slot-grid {
display: grid;
grid-template-columns: repeat(8, minmax(26px, 1fr));
gap: 6px;
margin-top: 10px;
}
.slot-btn {
border: 1px solid #bfd3e8;
background: #f4f9ff;
color: #134068;
border-radius: 5px;
font-size: 11px;
line-height: 1;
padding: 7px 0;
cursor: pointer;
text-align: center;
width: 100%;
}
.slot-btn.slot-filled {
background: #fce8e8;
border-color: #e7adad;
color: #8d1f1f;
cursor: not-allowed;
}
.oldest-highlight {
border: 1px solid #ffd58f;
background: #fff8ea;
border-radius: 10px;
padding: 12px;
}
#biorepoTable tfoot input {
width: 100%;
min-width: 90px;
font-size: 11px;
padding: 4px 6px;
}
</style>
@endpush
@section('content')
<div class="wrapper">
<div class="container-fluid">
<div class="row">
<div class="col-sm-12">
<div class="page-title-box">
<div class="btn-group pull-right">
<ol class="breadcrumb hide-phone p-0 m-0">
<li class="breadcrumb-item active">Biorepository</li>
</ol>
</div>
<h4 class="page-title">Biorepository Lab Mikrobiologi</h4>
</div>
</div>
</div>
@if(session('success'))
<div class="row">
<div class="col-lg-12">
<div class="alert alert-success">{{ session('success') }}</div>
</div>
</div>
@endif
@if($errors->any())
<div class="row">
<div class="col-lg-12">
<div class="alert alert-danger">
@foreach($errors->all() as $err)
<div>{{ $err }}</div>
@endforeach
</div>
</div>
</div>
@endif
<div class="row">
<div class="col-md-4">
<div class="card-box bio-summary-card">
<h5>Total Lemari</h5>
<h3>{{ $totalCabinets }}</h3>
<button type="button" class="btn btn-sm btn-primary" data-toggle="modal" data-target="#modalTambahLemari">Tambah Lemari</button>
</div>
</div>
<div class="col-md-4">
<div class="card-box bio-summary-card">
<h5>Total Rack</h5>
<h3>{{ $totalRacks }}</h3>
<button type="button" class="btn btn-sm btn-info" data-toggle="modal" data-target="#modalTambahRack">Tambah Rack</button>
</div>
</div>
<div class="col-md-4">
<div class="card-box bio-summary-card">
<h5>Total Spesimen</h5>
<h3>{{ $totalSpecimens }}</h3>
<button type="button" class="btn btn-sm btn-dark" id="btnOpenListTab">Lihat List</button>
</div>
</div>
</div>
<div class="card-box">
<ul class="nav nav-tabs m-b-20">
<li class="nav-item">
<a href="#tabVisual" data-toggle="tab" aria-expanded="true" class="nav-link active">Visualisasi</a>
</li>
<li class="nav-item">
<a href="#tabList" data-toggle="tab" aria-expanded="false" class="nav-link" id="tabListLink">List Biorepository</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tabVisual">
<h4 class="m-b-15">Spesimen dengan Waktu Simpan Paling Lama</h4>
@if($oldestSpecimen)
<div class="oldest-highlight m-b-20">
<strong>{{ $oldestSpecimen->specimen_code }}</strong> - {{ $oldestSpecimen->bacteria_name ?? $oldestSpecimen->specimen_name }}<br>
Lemari: {{ $oldestSpecimen->cabinet->name ?? '-' }} | Rack: {{ $oldestSpecimen->rack->name ?? '-' }}<br>
Disimpan sejak: {{ $oldestSpecimen->stored_at }} ({{ $oldestStorageDays }} hari)
</div>
@else
<div class="alert alert-warning m-b-20">Belum ada data spesimen.</div>
@endif
<h4 class="m-b-20">Visualisasi Lemari, Rack, dan Slot</h4>
<p class="text-muted">Klik slot berwarna biru untuk mengisi spesimen. Slot merah artinya sudah terisi.</p>
@forelse($cabinets as $cabinet)
<div class="cabinet-visual">
<h5 class="m-b-15">{{ $cabinet->code }} - {{ $cabinet->name }} <small class="text-muted">({{ $cabinet->location ?? 'Lokasi belum diisi' }})</small></h5>
<div class="rack-grid">
@forelse($cabinet->racks as $rack)
@php
$slotMap = [];
foreach ($rack->specimens as $item) {
if ($item->slot_number) {
$slotMap[$item->slot_number] = $item;
}
}
$capacity = (int) $rack->capacity;
@endphp
<div class="rack-box">
<div class="rack-header">{{ $rack->code }} - {{ $rack->name }}</div>
<div style="font-size:12px;">Shelf {{ $rack->level }} | Rack {{ $rack->rack_number ?? $rack->id }} | Box {{ $rack->box_number ?? 1 }}</div>
<div style="font-size:12px;">Slot: {{ $capacity }} | Terisi: {{ $rack->specimens->count() }}</div>
@if($capacity > 0)
<div class="slot-grid">
@for($i = 1; $i <= $capacity; $i++)
@if(isset($slotMap[$i]))
<div class="slot-btn slot-filled" title="{{ $slotMap[$i]->specimen_code }} - {{ $slotMap[$i]->bacteria_name ?? $slotMap[$i]->specimen_name }}">{{ $i }}</div>
@else
<button type="button"
class="slot-btn js-slot"
data-rack-id="{{ $rack->id }}"
data-shelf="{{ $rack->level }}"
data-rackno="{{ $rack->rack_number ?? $rack->id }}"
data-slot="{{ $i }}"
data-box="{{ $rack->box_number ?? 1 }}">
{{ $i }}
</button>
@endif
@endfor
</div>
@else
<div class="alert alert-light m-b-0 m-t-10">Kapasitas slot belum diatur.</div>
@endif
</div>
@empty
<div class="alert alert-light m-b-0">Belum ada rack pada lemari ini.</div>
@endforelse
</div>
</div>
@empty
<div class="alert alert-warning">Belum ada data lemari biorepository.</div>
@endforelse
</div>
<div class="tab-pane" id="tabList">
<h4 class="m-b-20">List Biorepository</h4>
<div class="table-responsive">
<table id="biorepoTable" class="table table-bordered table-striped table-sm">
<thead>
<tr>
<th>Kode Sample</th>
<th>Kategori</th>
<th>Shelf</th>
<th>Rack</th>
<th>Slot</th>
<th>Box</th>
<th>Tube</th>
<th>Bactery</th>
<th>Strain</th>
<th>Lemari</th>
<th>Nama Rack</th>
<th>Tgl Simpan</th>
<th>Input By</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Kode Sample</th>
<th>Kategori</th>
<th>Shelf</th>
<th>Rack</th>
<th>Slot</th>
<th>Box</th>
<th>Tube</th>
<th>Bactery</th>
<th>Strain</th>
<th>Lemari</th>
<th>Nama Rack</th>
<th>Tgl Simpan</th>
<th>Input By</th>
</tr>
</tfoot>
<tbody>
@foreach($specimenRows as $row)
<tr>
<td>{{ $row->specimen_code }}</td>
<td>{{ $row->category_storage }}</td>
<td>{{ $row->shelf_number }}</td>
<td>{{ $row->rack_number }}</td>
<td>{{ $row->slot_number }}</td>
<td>{{ $row->box_number }}</td>
<td>{{ $row->tube_number }}</td>
<td>{{ $row->bacteria_name ?? $row->specimen_name }}</td>
<td>{{ $row->strain }}</td>
<td>{{ $row->cabinet->code ?? '-' }}</td>
<td>{{ $row->rack->name ?? '-' }}</td>
<td>{{ $row->stored_at }}</td>
<td>{{ $row->input_by }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="modalTambahLemari" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Tambah Lemari</h4>
</div>
<form method="POST" action="{{ route('biorepository.storeCabinet') }}">
@csrf
<div class="modal-body">
<div class="form-group">
<label>Kode Lemari</label>
<input type="text" name="code" class="form-control" placeholder="LMR-A01" required>
</div>
<div class="form-group">
<label>Nama Lemari</label>
<input type="text" name="name" class="form-control" required>
</div>
<div class="form-group">
<label>Lokasi</label>
<input type="text" name="location" class="form-control" placeholder="Ruang kultur 1">
</div>
<div class="form-group m-b-0">
<label>Catatan</label>
<textarea name="notes" class="form-control" rows="2"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Batal</button>
<button class="btn btn-primary" type="submit">Simpan Lemari</button>
</div>
</form>
</div>
</div>
</div>
<div id="modalTambahRack" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Tambah Rack</h4>
</div>
<form method="POST" action="{{ route('biorepository.storeRack') }}">
@csrf
<div class="modal-body">
<div class="form-group">
<label>Pilih Lemari</label>
<select name="cabinet_id" class="form-control" required>
<option value="">-- Pilih --</option>
@foreach($cabinetOptions as $cab)
<option value="{{ $cab->id }}">{{ $cab->code }} - {{ $cab->name }}</option>
@endforeach
</select>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label>Kode Rack</label>
<input type="text" name="code" class="form-control" placeholder="R01" required>
</div>
<div class="form-group col-md-6">
<label>Nama Rack</label>
<input type="text" name="name" class="form-control" required>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-3">
<label>Shelf</label>
<input type="number" name="level" class="form-control" min="1" value="1" required>
</div>
<div class="form-group col-md-3">
<label>Rack No</label>
<input type="number" name="rack_number" class="form-control" min="1" value="1" required>
</div>
<div class="form-group col-md-3">
<label>Box No</label>
<input type="number" name="box_number" class="form-control" min="1" value="1" required>
</div>
<div class="form-group col-md-3">
<label>Jumlah Slot</label>
<input type="number" name="capacity" class="form-control" min="1" value="24" required>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Batal</button>
<button class="btn btn-info" type="submit">Simpan Rack</button>
</div>
</form>
</div>
</div>
</div>
<div id="modalIsiSlot" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Isi Spesimen ke Slot</h4>
</div>
<form method="POST" action="{{ route('biorepository.storeSpecimen') }}">
@csrf
<div class="modal-body">
<input type="hidden" id="rack_id" name="rack_id">
<div class="form-group m-b-25">
<div class="col-12">
<label>Category Penyimpanan</label>
<select class="form-control" id="kategorisimpan" name="kategorisimpan">
<option value="A">Penyimpanan Suhu Ruang</option>
<option value="B">Penyimpanan Suhu 4 Derajat</option>
<option value="C">Penyimpanan Suhu 20 Derajat</option>
<option value="D">Penyimpanan Suhu 80 Derajat</option>
</select>
</div>
</div>
<div class="form-group row">
<div class="col-lg-4">
<label>Shelf Nomor</label>
<input type="number" class="form-control" id="shelfnomor" name="shelfnomor" readonly>
</div>
<div class="col-lg-4">
<label>Rack Number</label>
<input type="number" class="form-control" id="raknomor" name="raknomor" readonly>
</div>
<div class="col-lg-4">
<label>Slot Number</label>
<input type="number" class="form-control" id="slotnomor" name="slotnomor" readonly>
</div>
<div class="col-lg-4">
<label>Box Number</label>
<input type="number" class="form-control" id="boxnomor" name="boxnomor" readonly>
</div>
<div class="col-lg-4">
<label>Tube Number</label>
<input type="number" class="form-control" id="tubenomor" name="tubenomor" required>
</div>
<div class="col-lg-4">
<label>Tanggal Simpan</label>
<input type="date" class="form-control" id="stored_at" name="stored_at" value="{{ date('Y-m-d') }}" required>
</div>
</div>
<div class="form-group m-b-25">
<div class="col-12">
<label>Bactery Name</label>
<input type="text" class="form-control" id="nmbakteri" name="nmbakteri" required>
</div>
</div>
<div class="form-group m-b-25">
<div class="col-12">
<label>Strain</label>
<select class="form-control" id="strain" name="strain">
<option value="Gram Negatif">Gram Negatif</option>
<option value="Gram Positif">Gram Positif</option>
</select>
</div>
</div>
<div class="form-group m-b-0">
<div class="col-12">
<label>Sample Code (Preview Otomatis)</label>
<input type="text" class="form-control" id="samplecodepreview" readonly>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Batal</button>
<button type="submit" class="btn btn-primary">Simpan Spesimen</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('script')
<script>
function buildSampleCodePreview() {
var category = $('#kategorisimpan').val() || '';
var shelf = $('#shelfnomor').val() || '';
var rack = $('#raknomor').val() || '';
var slot = $('#slotnomor').val() || '';
var box = $('#boxnomor').val() || '';
var tube = $('#tubenomor').val() || '';
var code = [category, shelf, rack, slot, box, tube].join('-');
$('#samplecodepreview').val(code);
}
$(document).on('click', '.js-slot', function () {
$('#rack_id').val($(this).data('rack-id'));
$('#shelfnomor').val($(this).data('shelf'));
$('#raknomor').val($(this).data('rackno'));
$('#slotnomor').val($(this).data('slot'));
$('#boxnomor').val($(this).data('box'));
$('#tubenomor').val('');
buildSampleCodePreview();
$('#modalIsiSlot').modal('show');
});
$(document).on('keyup change', '#kategorisimpan, #shelfnomor, #raknomor, #slotnomor, #boxnomor, #tubenomor', function () {
buildSampleCodePreview();
});
$(function () {
$('#biorepoTable tfoot th').each(function () {
var title = $(this).text();
$(this).html('<input type="text" placeholder="Filter ' + title + '" />');
});
var table = $('#biorepoTable').DataTable({
order: [[11, 'desc']],
pageLength: 25
});
table.columns().every(function () {
var that = this;
$('input', this.footer()).on('keyup change clear', function () {
if (that.search() !== this.value) {
that.search(this.value).draw();
}
});
});
$('#btnOpenListTab').on('click', function () {
$('#tabListLink').tab('show');
});
});
</script>
@endpush