This commit is contained in:
Dwi Swandhana
2026-02-21 05:39:38 +07:00
parent dea0da9357
commit f2e562564d
2 changed files with 206 additions and 94 deletions
@@ -23,6 +23,10 @@ class BiorepositoryController extends Controller
$data['totalCabinets'] = BioCabinet::count();
$data['totalRacks'] = BioRack::count();
$data['totalSpecimens'] = BioSpecimen::count();
$data['specimenRows'] = BioSpecimen::with(['cabinet', 'rack'])
->orderBy('stored_at', 'DESC')
->orderBy('id', 'DESC')
->get();
$data['cabinets'] = BioCabinet::with([
'racks' => function ($query) {
@@ -44,6 +44,7 @@
padding: 7px 0;
cursor: pointer;
text-align: center;
width: 100%;
}
.slot-btn.slot-filled {
background: #fce8e8;
@@ -57,6 +58,12 @@
border-radius: 10px;
padding: 12px;
}
#biorepoTable tfoot input {
width: 100%;
min-width: 90px;
font-size: 11px;
padding: 4px 6px;
}
</style>
@endpush
@@ -101,119 +108,48 @@
<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="row">
<div class="col-lg-6">
<div class="card-box ribbon-box">
<div class="ribbon ribbon-primary">Tambah Lemari</div>
<p class="m-b-0"></p>
<form method="POST" action="{{ route('biorepository.storeCabinet') }}">
@csrf
<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">
<label>Catatan</label>
<textarea name="notes" class="form-control" rows="2"></textarea>
</div>
<button class="btn btn-custom btn-block" type="submit">Simpan Lemari</button>
</form>
</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="col-lg-6">
<div class="card-box ribbon-box">
<div class="ribbon ribbon-info">Tambah Rack</div>
<p class="m-b-0"></p>
<form method="POST" action="{{ route('biorepository.storeRack') }}">
@csrf
<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>
<button class="btn btn-info btn-block" type="submit">Simpan Rack</button>
</form>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="card-box">
<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">
<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-0">Belum ada data spesimen.</div>
<div class="alert alert-warning m-b-20">Belum ada data spesimen.</div>
@endif
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="card-box">
<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>
@@ -267,11 +203,165 @@
<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">
@@ -340,13 +430,6 @@
</div>
</div>
<div class="form-group m-b-25">
<div class="col-12">
<label>ATCC (Otomatis dari User Login)</label>
<input type="text" class="form-control" id="atcc" name="atcc" value="{{ Session('nama') }}" readonly>
</div>
</div>
<div class="form-group m-b-0">
<div class="col-12">
<label>Sample Code (Preview Otomatis)</label>
@@ -391,5 +474,30 @@
$(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