This commit is contained in:
Dwi Swandhana
2026-07-03 20:48:38 +07:00
parent ed92325536
commit f857eec85c
11 changed files with 1820 additions and 1142 deletions
@@ -17,6 +17,72 @@
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 12px;
}
.bio-step-panel {
border: 1px solid #d7e3ef;
border-radius: 8px;
background: #ffffff;
padding: 12px;
margin-bottom: 14px;
}
.bio-step-title {
font-weight: 700;
color: #1b3a57;
margin-bottom: 10px;
}
.bio-choice-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 10px;
}
.bio-choice-wrap {
position: relative;
}
.bio-choice {
display: block;
width: 100%;
min-height: 92px;
border: 1px solid #d7e3ef;
border-radius: 6px;
background: #f8fbff;
color: #1b3a57;
text-align: left;
padding: 10px;
cursor: pointer;
}
.bio-choice strong,
.bio-choice span,
.bio-choice small {
display: block;
}
.bio-choice small {
color: #6c757d;
margin-top: 3px;
}
.bio-choice.active,
.bio-number.active {
border-color: #188ae2;
background: #eaf5ff;
box-shadow: inset 0 0 0 1px #188ae2;
}
.bio-delete-form {
position: absolute;
top: 8px;
right: 8px;
}
.bio-number-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
gap: 8px;
}
.bio-number {
border: 1px solid #d7e3ef;
border-radius: 6px;
background: #f8fbff;
color: #1b3a57;
padding: 9px 6px;
cursor: pointer;
text-align: center;
}
.rack-box {
border: 1px solid #d7e3ef;
border-radius: 10px;
@@ -58,6 +124,7 @@
cursor: pointer;
text-align: center;
width: 100%;
min-height: 34px;
}
.slot-btn.slot-filled {
background: #fce8e8;
@@ -65,6 +132,10 @@
color: #8d1f1f;
cursor: pointer;
}
.slot-btn span,
.slot-btn small {
display: block;
}
.oldest-highlight {
border: 1px solid #ffd58f;
background: #fff8ea;
@@ -163,94 +234,10 @@
<div class="alert alert-warning m-b-20">Belum ada data spesimen.</div>
@endif
<h4 class="m-b-20">Visualisasi Lemari, Rack, Shelf, Box, dan Tube</h4>
<p class="text-muted">Klik nomor tube berwarna biru untuk mengisi spesimen. Tube merah artinya sudah terisi.</p>
<h4 class="m-b-20">Visualisasi Lemari, Rack, Slot, Shelf, Box, dan Tube</h4>
<p class="text-muted">Pilih posisi dari lemari sampai box. Tube biru bisa diisi, tube merah sudah terisi.</p>
@forelse($cabinets as $cabinet)
<div class="cabinet-visual">
<div class="d-flex justify-content-between align-items-start m-b-15">
<h5 class="m-b-0">{{ $cabinet->code }} - {{ $cabinet->name }} <small class="text-muted">({{ $cabinet->location ?? 'Lokasi belum diisi' }})</small></h5>
<form method="POST" action="{{ route('biorepository.deleteCabinet', $cabinet->id) }}" class="js-delete-cabinet">
@csrf
<button type="submit" class="btn btn-sm btn-danger">Delete Lemari</button>
</form>
</div>
<div class="rack-grid">
@forelse($cabinet->racks as $rack)
@php
$tubeMap = [];
foreach ($rack->specimens as $item) {
if ($item->shelf_number && $item->tube_number) {
$tubeMap[$item->shelf_number.'-'.$item->tube_number] = $item;
}
}
$shelfCount = (int) $rack->level;
$tubeCapacity = (int) $rack->capacity;
@endphp
<div class="rack-box">
<div class="d-flex justify-content-between align-items-start">
<div class="rack-header">{{ $rack->code }} - {{ $rack->name }}</div>
<form method="POST" action="{{ route('biorepository.deleteRack', $rack->id) }}" class="js-delete-rack">
@csrf
<button type="submit" class="btn btn-xs btn-danger">Delete Rack</button>
</form>
</div>
<div style="font-size:12px;">Rack No {{ $rack->rack_number ?? $rack->id }} | Total Shelf {{ $shelfCount }} | 1 Box per Shelf | Tube per Box {{ $tubeCapacity }}</div>
<div style="font-size:12px;">Terisi: {{ $rack->specimens->count() }}</div>
@if($shelfCount > 0 && $tubeCapacity > 0)
@for($shelf = 1; $shelf <= $shelfCount; $shelf++)
<div class="shelf-section">
<div style="font-size:12px;"><b>Shelf {{ $shelf }}</b> - Box 1 (Tube 1-{{ $tubeCapacity }})</div>
<div class="tube-grid">
@for($tube = 1; $tube <= $tubeCapacity; $tube++)
@php $tubeKey = $shelf.'-'.$tube; @endphp
@if(isset($tubeMap[$tubeKey]))
<button type="button"
class="slot-btn slot-filled js-slot-filled"
style="font-size:7px; line-height:1.1; padding:4px 2px;"
data-specimen-id="{{ $tubeMap[$tubeKey]->id }}"
data-rack-id="{{ $rack->id }}"
data-shelf="{{ $shelf }}"
data-rackno="{{ $rack->rack_number ?? $rack->id }}"
data-slot="{{ $shelf }}"
data-box="1"
data-tube="{{ $tube }}"
data-bakteri="{{ $tubeMap[$tubeKey]->bacteria_name ?? $tubeMap[$tubeKey]->specimen_name }}"
data-strain="{{ $tubeMap[$tubeKey]->strain }}"
data-volume="{{ $tubeMap[$tubeKey]->volume ?? 0 }}"
title="{{ $tubeMap[$tubeKey]->specimen_code }} - {{ $tubeMap[$tubeKey]->bacteria_name ?? $tubeMap[$tubeKey]->specimen_name }} / {{ $tubeMap[$tubeKey]->strain }}">
{{ ($tubeMap[$tubeKey]->bacteria_name ?? $tubeMap[$tubeKey]->specimen_name) }} / {{ $tubeMap[$tubeKey]->strain ?? '-' }}<br />
{{ $tubeMap[$tubeKey]->volume ?? 0 }} ml
</button>
@else
<button type="button"
class="slot-btn js-slot"
data-rack-id="{{ $rack->id }}"
data-shelf="{{ $shelf }}"
data-rackno="{{ $rack->rack_number ?? $rack->id }}"
data-slot="{{ $shelf }}"
data-box="1"
data-tube="{{ $tube }}">
{{ $tube }}
</button>
@endif
@endfor
</div>
</div>
@endfor
@else
<div class="alert alert-light m-b-0 m-t-10">Konfigurasi rack belum lengkap.</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
@livewire('biorepository-visual')
</div>
<div class="tab-pane" id="tabList">
@@ -405,15 +392,25 @@
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label>Jumlah Shelf per Rack (4-6)</label>
<label>Jumlah Slot per Rack</label>
<input type="number" name="slot_count" class="form-control" min="1" max="20" value="1" required>
</div>
<div class="form-group col-md-6">
<label>Jumlah Shelf per Slot (4-6)</label>
<input type="number" name="level" class="form-control" min="4" max="6" value="4" required>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label>Jumlah Box per Shelf</label>
<input type="number" name="box_number" class="form-control" min="1" max="20" value="1" required>
</div>
<div class="form-group col-md-6">
<label>Tube per Box (16-100)</label>
<input type="number" name="capacity" class="form-control" min="16" max="100" value="16" required>
</div>
</div>
<small class="text-muted">Rack number dibuat otomatis oleh sistem. Struktur: 1 rack memiliki 4-6 shelf, setiap shelf memiliki 1 box, setiap box 16-100 tube.</small>
<small class="text-muted">Rack number dibuat otomatis oleh sistem. Struktur: lemari -> rack -> slot -> shelf -> box -> tube.</small>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Batal</button>
@@ -459,11 +456,11 @@
<input type="number" class="form-control" id="raknomor" name="raknomor" readonly>
</div>
<div class="col-lg-4">
<label>Slot Number (Sama dengan Shelf)</label>
<label>Slot Number</label>
<input type="number" class="form-control" id="slotnomor" name="slotnomor" readonly>
</div>
<div class="col-lg-4">
<label>Box Number (1 per Shelf)</label>
<label>Box Number</label>
<input type="number" class="form-control" id="boxnomor" name="boxnomor" readonly>
</div>
<div class="col-lg-4">