initial commit

This commit is contained in:
2026-09-23 12:45:02 +07:00
parent d16f454083
commit 507fc6ccdf
235 changed files with 19587 additions and 2835 deletions
@@ -0,0 +1,92 @@
<x-app-layout>
<div class="max-w-4xl mx-auto py-12 px-4">
{{-- Header & Back Button --}}
<div class="flex items-center gap-6 mb-10">
<a href="{{ route('cats.index') }}" class="p-4 bg-white border border-slate-200 rounded-2xl text-slate-400 hover:text-emerald-600 transition-all shadow-sm active:scale-90">
<i class="fas fa-arrow-left"></i>
</a>
<div>
<h2 class="text-2xl font-black text-slate-800 uppercase tracking-tight">Bulk Berat Update</h2>
<p class="text-sm text-slate-400 font-bold uppercase tracking-widest">Perbarui berat badan massal via Excel/CSV</p>
</div>
</div>
<div class="bg-white rounded-[3rem] shadow-xl border border-slate-100 p-10 md:p-14 overflow-hidden">
{{-- Langkah 1: Unduh --}}
<div class="flex flex-col md:flex-row items-start md:items-center gap-6 p-8 bg-slate-50 rounded-[2rem] border border-slate-100 mb-10">
<div class="w-16 h-16 bg-white text-indigo-600 rounded-2xl flex items-center justify-center shrink-0 shadow-sm border border-slate-100">
<i class="fas fa-file-csv text-3xl"></i>
</div>
<div class="flex-1">
<h4 class="font-black text-slate-800 uppercase text-sm mb-2">Langkah 1: Unduh Format CSV</h4>
<p class="text-xs text-slate-500 mb-0 leading-relaxed font-medium">
Sistem akan mengunduh daftar kucing saat ini beserta <b>Kode Kucing</b>-nya.<br>
Cukup isi angka pada kolom <b>Berat Badan (Kg)</b>. Anda juga dapat mengubah <b>Tanggal</b> untuk mencatat data timbangan di masa lalu (Backdate).
</p>
</div>
<div class="shrink-0 mt-4 md:mt-0 w-full md:w-auto">
<a href="{{ route('cats.weight-template') }}" class="flex items-center justify-center px-6 py-4 bg-indigo-50 border border-indigo-100 text-indigo-700 text-[10px] font-black rounded-2xl hover:bg-indigo-600 hover:text-white transition-all shadow-sm uppercase tracking-widest w-full">
<i class="fas fa-download mr-2 text-sm"></i> Unduh Template
</a>
</div>
</div>
{{-- Langkah 2: Unggah Form --}}
<form action="{{ route('cats.bulk-weight.post') }}" method="POST" enctype="multipart/form-data" class="space-y-8">
@csrf
<div class="space-y-4">
<label class="text-xs font-black text-slate-800 uppercase tracking-widest ml-2">Langkah 2: Unggah Data Terbaru</label>
<div class="relative group">
<input type="file" name="file_excel" id="file_excel" required accept=".csv, .xlsx, .xls" onchange="updateFileName(this)" class="absolute inset-0 w-full h-full opacity-0 cursor-pointer z-10">
<div id="upload-box" class="w-full p-16 border-2 border-dashed border-slate-300 rounded-[2.5rem] bg-white text-center group-hover:border-emerald-500 group-hover:bg-emerald-50 transition-all">
<i id="upload-icon" class="fas fa-cloud-upload-alt text-6xl text-slate-300 group-hover:text-emerald-500 mb-6 transition-colors"></i>
<p id="upload-text" class="text-xs font-black text-slate-600 uppercase tracking-widest">Klik atau Seret File Excel/CSV ke Sini</p>
<p id="file-name" class="text-sm font-bold text-emerald-600 mt-4 hidden bg-white px-4 py-2 rounded-lg inline-block shadow-sm border border-emerald-100"></p>
</div>
</div>
</div>
<div class="pt-4 border-t border-slate-100">
<button type="submit" class="w-full py-6 bg-emerald-600 text-white rounded-[2rem] font-black uppercase text-xs tracking-[0.3em] shadow-xl shadow-emerald-200 hover:bg-emerald-700 transition-all active:scale-95">
<i class="fas fa-check-circle mr-2 text-sm"></i> PROSES BULK UPDATE
</button>
</div>
</form>
</div>
</div>
@push('scripts')
<script>
// Script untuk mengubah tampilan UI saat file dipilih oleh user
function updateFileName(input) {
const fileName = input.files[0]?.name;
const textEl = document.getElementById('upload-text');
const nameEl = document.getElementById('file-name');
const iconEl = document.getElementById('upload-icon');
const boxEl = document.getElementById('upload-box');
if (fileName) {
textEl.innerText = "File Siap Diproses:";
nameEl.innerText = fileName;
nameEl.classList.remove('hidden');
iconEl.classList.replace('fa-cloud-upload-alt', 'fa-file-excel');
iconEl.classList.replace('text-slate-300', 'text-emerald-500');
boxEl.classList.replace('border-slate-300', 'border-emerald-500');
boxEl.classList.replace('bg-white', 'bg-emerald-50');
} else {
textEl.innerText = "Klik atau Seret File Excel/CSV ke Sini";
nameEl.classList.add('hidden');
iconEl.classList.replace('fa-file-excel', 'fa-cloud-upload-alt');
iconEl.classList.replace('text-emerald-500', 'text-slate-300');
boxEl.classList.replace('border-emerald-500', 'border-slate-300');
boxEl.classList.replace('bg-emerald-50', 'bg-white');
}
}
</script>
@endpush
</x-app-layout>
+97 -64
View File
@@ -6,8 +6,8 @@
<i class="fas fa-arrow-left"></i>
</a>
<div>
<h2 class="text-2xl font-black text-slate-800 tracking-tight uppercase">Tambah Kucing Baru</h2>
<p class="text-sm text-slate-500 font-medium italic tracking-tight">Registrasi identitas permanen & silsilah ke database Ilycats.</p>
<h2 class="text-2xl font-black text-slate-800 tracking-tight uppercase leading-none mb-1">Tambah Kucing Baru</h2>
<p class="text-[10px] text-slate-400 font-bold uppercase tracking-[0.2em]">Registrasi Identitas Permanen • Ilycats Database</p>
</div>
</div>
@@ -30,31 +30,38 @@
@csrf
{{-- SECTION 1: IDENTITAS UTAMA --}}
<div class="bg-white border border-slate-200 rounded-[2.5rem] p-8 shadow-sm space-y-6">
<h4 class="text-xs font-black text-indigo-600 uppercase tracking-widest border-b border-slate-100 pb-4 mb-2 flex items-center gap-2 italic">
<i class="fas fa-id-card"></i> Identitas & Dokumen Resmi
</h4>
<div class="bg-white border border-slate-200 rounded-[2.5rem] p-8 shadow-sm space-y-8">
<div class="flex items-center gap-4 mb-2 border-b border-slate-100 pb-4">
<div class="w-8 h-8 bg-indigo-600 text-white rounded-xl flex items-center justify-center text-xs shadow-lg">
<i class="fas fa-id-card"></i>
</div>
<h4 class="font-black text-slate-800 uppercase tracking-tighter text-lg">Identitas & Dokumen Resmi</h4>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
{{-- Nama Kucing --}}
<div class="space-y-2 md:col-span-2">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Nama Lengkap Kucing (Sesuai Pedigree)</label>
<input type="text" name="nama_kucing" value="{{ old('nama_kucing') }}" required placeholder="Contoh: Earrin Cats Moonlight" class="w-full px-4 py-4 bg-slate-50 border border-slate-200 rounded-2xl focus:ring-2 focus:ring-indigo-500 transition-all text-sm font-bold text-slate-800">
<input type="text" name="nama_kucing" value="{{ old('nama_kucing') }}" required placeholder="Contoh: Earrin Cats Moonlight" class="w-full px-5 py-4 bg-slate-50 border border-slate-200 rounded-2xl focus:ring-4 focus:ring-indigo-500/10 focus:border-indigo-500 transition-all text-sm font-bold text-slate-800">
</div>
{{-- No. Pedigree, Microchip, & EMS (GRID 3 KOLOM) --}}
<div class="md:col-span-2 grid grid-cols-1 md:grid-cols-3 gap-4">
{{-- GRID IDENTITAS --}}
<div class="md:col-span-2 grid grid-cols-1 md:grid-cols-3 gap-4 border-y border-slate-50 py-6 my-2">
<div class="space-y-2">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">No. Pedigree</label>
<input type="text" name="pedigree" value="{{ old('pedigree') }}" placeholder="ICA.LO.xxxx" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl focus:ring-2 focus:ring-indigo-500 transition-all text-xs font-bold text-slate-800">
{{-- PERBAIKAN: Menghapus class 'uppercase' agar input sesuai ketikan --}}
<input type="text" name="pedigree" value="{{ old('pedigree') }}" placeholder="ICA.LO.xxxx" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl focus:ring-2 focus:ring-indigo-500 text-xs font-bold text-slate-800">
</div>
<div class="space-y-2">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">No. Microchip</label>
<input type="text" name="microchip" value="{{ old('microchip') }}" placeholder="90011xxxx" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl focus:ring-2 focus:ring-indigo-500 transition-all text-xs font-bold text-slate-800">
<input type="text" name="microchip" value="{{ old('microchip') }}" placeholder="90011xxxx" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl focus:ring-2 focus:ring-indigo-500 text-xs font-bold text-slate-800">
</div>
<div class="space-y-2">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Kode EMS</label>
<input type="text" name="kode_ems" value="{{ old('kode_ems') }}" placeholder="PER d 03" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl focus:ring-2 focus:ring-indigo-500 transition-all text-xs font-bold text-slate-800">
<label class="text-[10px] font-black text-indigo-600 uppercase tracking-widest ml-1 flex items-center gap-2">
<i class="fas fa-dna text-[10px]"></i> Kode EMS
</label>
{{-- PERBAIKAN: Menghapus class 'uppercase' agar input sesuai ketikan --}}
<input type="text" name="kode_ems" value="{{ old('kode_ems') }}" placeholder="PER d 03" class="w-full px-4 py-3 bg-indigo-50/30 border border-indigo-100 rounded-xl focus:ring-2 focus:ring-indigo-500 text-xs font-black text-indigo-700">
</div>
</div>
@@ -62,9 +69,9 @@
<div class="space-y-2">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Ras / Breed</label>
<select name="ras" required class="w-full px-4 py-4 bg-slate-50 border border-slate-200 rounded-2xl focus:ring-2 focus:ring-indigo-500 transition-all text-sm font-bold text-slate-800">
<option value="Persian" {{ old('ras') == 'Persian' ? 'selected' : '' }}>Persian</option>
<option value="British Shorthair" {{ old('ras') == 'British Shorthair' ? 'selected' : '' }}>British Shorthair</option>
<option value="Lainnya" {{ old('ras') == 'Lainnya' ? 'selected' : '' }}>Lainnya</option>
@foreach(['Persian', 'British Shorthair', 'Scottish Fold', 'Maine Coon', 'Munchkin', 'Lainnya'] as $ras)
<option value="{{ $ras }}" {{ old('ras') == $ras ? 'selected' : '' }}>{{ $ras }}</option>
@endforeach
</select>
</div>
@@ -77,11 +84,11 @@
{{-- Registry --}}
<div class="md:col-span-2 space-y-3">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1 block">Federasi / Registry</label>
<div class="grid grid-cols-2 md:grid-cols-4 gap-3">
@foreach(['ICA', 'CFA', 'WCF', 'FFF'] as $reg)
<div class="grid grid-cols-2 md:grid-cols-5 gap-3">
@foreach(['ICA', 'CFA', 'WCF', 'FFF', 'NON-PED'] as $reg)
<label class="block cursor-pointer group">
<input type="checkbox" name="registry[]" value="{{ $reg }}"
{{ is_array(old('registry')) && in_array($reg, old('registry')) ? 'checked' : '' }}
{{ (is_array(old('registry')) && in_array($reg, old('registry'))) || ($reg === 'NON-PED' && !old('registry')) ? 'checked' : '' }}
class="sr-only peer">
<div class="py-4 text-center border-2 border-slate-100 rounded-2xl text-[10px] font-black text-slate-400
peer-checked:bg-indigo-600 peer-checked:text-white peer-checked:border-indigo-600
@@ -97,15 +104,15 @@
<div class="space-y-2 md:col-span-2">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Jenis Kelamin</label>
<div class="flex gap-4">
<label class="flex-1 cursor-pointer">
<input type="radio" name="jenis_kelamin" value="Jantan" {{ old('jenis_kelamin', 'Jantan') == 'Jantan' ? 'checked' : '' }} class="hidden peer">
<div class="p-4 text-center border-2 border-slate-100 rounded-2xl text-xs font-black text-slate-400 peer-checked:bg-blue-50 peer-checked:border-blue-500 peer-checked:text-blue-600 transition-all shadow-sm">
<label class="flex-1 cursor-pointer group">
<input type="radio" name="jenis_kelamin" value="Jantan" {{ old('jenis_kelamin', 'Jantan') == 'Jantan' ? 'checked' : '' }} class="sr-only peer">
<div class="p-4 text-center border-2 border-slate-100 rounded-2xl text-xs font-black text-slate-400 peer-checked:bg-blue-50 peer-checked:border-blue-500 peer-checked:text-blue-600 transition-all shadow-sm group-hover:border-slate-200">
<i class="fas fa-mars mr-2"></i> JANTAN (SIRE)
</div>
</label>
<label class="flex-1 cursor-pointer">
<input type="radio" name="jenis_kelamin" value="Betina" {{ old('jenis_kelamin') == 'Betina' ? 'checked' : '' }} class="hidden peer">
<div class="p-4 text-center border-2 border-slate-100 rounded-2xl text-xs font-black text-slate-400 peer-checked:bg-pink-50 peer-checked:border-pink-500 peer-checked:text-pink-600 transition-all shadow-sm">
<label class="flex-1 cursor-pointer group">
<input type="radio" name="jenis_kelamin" value="Betina" {{ old('jenis_kelamin') == 'Betina' ? 'checked' : '' }} class="sr-only peer">
<div class="p-4 text-center border-2 border-slate-100 rounded-2xl text-xs font-black text-slate-400 peer-checked:bg-pink-50 peer-checked:border-pink-500 peer-checked:text-pink-600 transition-all shadow-sm group-hover:border-slate-200">
<i class="fas fa-venus mr-2"></i> BETINA (DAM)
</div>
</label>
@@ -117,42 +124,46 @@
{{-- SECTION 2: GENETIK & LOKASI --}}
<div class="bg-white border border-slate-200 rounded-[2.5rem] p-8 shadow-sm space-y-6">
<h4 class="text-xs font-black text-indigo-600 uppercase tracking-widest border-b border-slate-100 pb-4 mb-2 flex items-center gap-2 italic">
<i class="fas fa-dna"></i> Penempatan & Silsilah Induk
<i class="fas fa-dna text-sm"></i> Penempatan & Silsilah Induk
</h4>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
{{-- Searchable Sire --}}
<div class="space-y-2">
<label class="text-[10px] font-bold text-slate-400 uppercase ml-1">Induk Jantan</label>
<select name="induk_jantan_id" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-2xl text-xs font-bold text-slate-700">
<option value="">-- Tanpa Sire --</option>
<label class="text-[10px] font-bold text-slate-400 uppercase ml-1">Induk Jantan (Sire)</label>
<input type="text" list="sire_list" id="sire_search" placeholder="Ketik nama sire..." class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-2xl text-xs font-bold text-slate-700 focus:ring-2 focus:ring-indigo-500" autocomplete="off">
<datalist id="sire_list">
@foreach($sires as $sire)
<option value="{{ $sire->id }}" {{ old('induk_jantan_id') == $sire->id ? 'selected' : '' }}>{{ $sire->nama_kucing }}</option>
<option data-id="{{ $sire->id }}" value="{{ $sire->nama_kucing }}">
@endforeach
</select>
</datalist>
<input type="hidden" name="induk_jantan_id" id="induk_jantan_id" value="{{ old('induk_jantan_id') }}">
</div>
{{-- Searchable Dam --}}
<div class="space-y-2">
<label class="text-[10px] font-bold text-slate-400 uppercase ml-1">Induk Betina</label>
<select name="induk_betina_id" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-2xl text-xs font-bold text-slate-700">
<option value="">-- Tanpa Dam --</option>
<label class="text-[10px] font-bold text-slate-400 uppercase ml-1">Induk Betina (Dam)</label>
<input type="text" list="dam_list" id="dam_search" placeholder="Ketik nama dam..." class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-2xl text-xs font-bold text-slate-700 focus:ring-2 focus:ring-indigo-500" autocomplete="off">
<datalist id="dam_list">
@foreach($dams as $dam)
<option value="{{ $dam->id }}" {{ old('induk_betina_id') == $dam->id ? 'selected' : '' }}>{{ $dam->nama_kucing }}</option>
<option data-id="{{ $dam->id }}" value="{{ $dam->nama_kucing }}">
@endforeach
</select>
</datalist>
<input type="hidden" name="induk_betina_id" id="induk_betina_id" value="{{ old('induk_betina_id') }}">
</div>
<div class="space-y-2">
<label class="text-[10px] font-bold text-slate-400 uppercase ml-1">Lokasi Kandang</label>
<select name="lokasi_kandang" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-2xl text-sm font-black text-indigo-600 uppercase">
@foreach(['A1', 'A2', 'Lorong', 'E1', 'E2'] as $loc)
<select name="lokasi_kandang" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-2xl text-sm font-black text-indigo-600 uppercase focus:ring-2 focus:ring-indigo-500">
@foreach(['A1', 'A2', 'Lorong', 'E1', 'E2', 'Karantina'] as $loc)
<option value="{{ $loc }}" {{ old('lokasi_kandang') == $loc ? 'selected' : '' }}>{{ $loc }}</option>
@endforeach
</select>
</div>
<div class="space-y-2">
<label class="text-[10px] font-bold text-slate-400 uppercase ml-1">PIC (Penanggung Jawab)</label>
<select name="pic_id" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-2xl text-xs font-bold text-slate-700">
<label class="text-[10px] font-bold text-slate-400 uppercase ml-1">PIC Bertugas</label>
<select name="pic_id" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-2xl text-xs font-bold text-slate-700 focus:ring-2 focus:ring-indigo-500">
@foreach($users as $user)
<option value="{{ $user->id }}" {{ old('pic_id', auth()->id()) == $user->id ? 'selected' : '' }}>{{ $user->name }}</option>
@endforeach
@@ -162,34 +173,33 @@
</div>
{{-- SECTION 3: JADWAL & PERTUMBUHAN --}}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
{{-- Jadwal Medis --}}
<div class="bg-white border border-slate-200 rounded-[2.5rem] p-8 shadow-sm space-y-4">
<h4 class="text-xs font-black text-rose-600 uppercase tracking-widest border-b border-slate-100 pb-4 mb-2 flex items-center gap-2 italic">
<i class="fas fa-calendar-alt"></i> Jadwal Perawatan
</h4>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div class="lg:col-span-2 bg-white border border-slate-200 rounded-[2.5rem] p-8 shadow-sm">
<div class="flex items-center gap-3 mb-6 border-b border-slate-100 pb-4">
<div class="w-7 h-7 bg-rose-50 text-rose-600 rounded-lg flex items-center justify-center text-[10px]">
<i class="fas fa-calendar-alt"></i>
</div>
<h4 class="text-xs font-black text-rose-600 uppercase tracking-widest italic">Jadwal Perawatan</h4>
</div>
<div class="grid grid-cols-2 gap-4">
@foreach (['vaksin', 'obat_cacing', 'obat_kutu', 'grooming'] as $task)
@foreach (['vaksin' => 'Vaksin', 'obat_cacing' => 'Obat Cacing', 'obat_kutu' => 'Obat Kutu', 'grooming' => 'Grooming'] as $task => $label)
<div class="space-y-1">
<label class="text-[9px] font-bold text-slate-400 uppercase ml-1">{{ str_replace('_', ' ', $task) }}</label>
<input type="date" name="jadwal_{{ $task }}" value="{{ old('jadwal_'.$task) }}" class="w-full p-3 bg-slate-50 border border-slate-200 rounded-xl text-[10px] font-black text-slate-700 focus:ring-rose-500">
<label class="text-[9px] font-bold text-slate-400 uppercase ml-1">{{ $label }}</label>
<input type="date" name="jadwal_{{ $task }}" value="{{ old('jadwal_'.$task) }}" class="w-full p-3 bg-slate-50 border border-slate-200 rounded-xl text-[10px] font-black text-slate-700 focus:ring-2 focus:ring-rose-200 transition-all">
</div>
@endforeach
</div>
</div>
{{-- Monitoring Berat --}}
<div class="bg-white border border-slate-200 rounded-[2.5rem] p-8 shadow-sm space-y-4">
<h4 class="text-xs font-black text-emerald-600 uppercase tracking-widest border-b border-slate-100 pb-4 mb-2 flex items-center gap-2 italic">
<i class="fas fa-weight-scale"></i> Vitalitas & Berat
<div class="bg-white border border-slate-200 rounded-[2.5rem] p-8 shadow-sm">
<h4 class="text-xs font-black text-emerald-600 uppercase tracking-widest border-b border-slate-100 pb-4 mb-6 italic flex items-center gap-2">
<i class="fas fa-weight-scale text-sm"></i> Vitalitas
</h4>
<div class="space-y-4">
<div>
<label class="text-[10px] font-black text-slate-400 uppercase ml-1">Berat Badan Awal</label>
<div class="relative mt-2">
<input type="number" step="0.01" name="berat_badan" value="{{ old('berat_badan') }}" placeholder="0.00" class="w-full pl-6 pr-14 py-5 bg-slate-50 border border-slate-200 rounded-3xl text-2xl font-black text-slate-800 focus:ring-emerald-500">
<span class="absolute right-6 top-1/2 -translate-y-1/2 text-xs font-black text-slate-400">KG</span>
</div>
<label class="text-[10px] font-black text-slate-400 uppercase ml-1">Berat Badan Awal</label>
<div class="relative mt-2">
<input type="number" step="0.01" name="berat_badan" value="{{ old('berat_badan') }}" placeholder="0.00" class="w-full pl-6 pr-14 py-5 bg-slate-50 border border-slate-200 rounded-3xl text-2xl font-black text-slate-800 focus:ring-4 focus:ring-emerald-500/10 focus:border-emerald-500 transition-all">
<span class="absolute right-6 top-1/2 -translate-y-1/2 text-xs font-black text-slate-400">KG</span>
</div>
</div>
</div>
@@ -197,9 +207,9 @@
{{-- SECTION 4: FOTO --}}
<div class="bg-white border border-slate-200 rounded-[2.5rem] p-8 shadow-sm space-y-4">
<h4 class="text-xs font-black text-slate-800 uppercase tracking-widest ml-1 mb-2">Unggah Foto Utama</h4>
<h4 class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1 mb-2">Unggah Foto Utama</h4>
<div class="relative group">
<input type="file" name="foto" id="foto" class="hidden" onchange="previewImage(event)">
<input type="file" name="foto" id="foto" class="hidden" onchange="previewImage(event)" accept="image/*">
<label for="foto" class="flex flex-col items-center justify-center border-4 border-dashed border-slate-100 rounded-[3rem] p-12 text-center cursor-pointer hover:border-indigo-200 hover:bg-indigo-50/20 transition-all duration-500 group">
<div id="preview-container" class="hidden mb-6">
<img id="image-preview" class="w-48 h-48 rounded-[2.5rem] object-cover shadow-2xl ring-8 ring-white">
@@ -210,7 +220,7 @@
</div>
<div>
<p class="text-xs text-slate-600 font-black tracking-widest uppercase">Pilih Foto Terbaik</p>
<p class="text-[10px] text-slate-400 mt-1 uppercase font-bold tracking-tighter italic">JPG, PNG, WEBP (Maks 2MB)</p>
<p class="text-[10px] text-slate-400 mt-1 uppercase font-bold tracking-tighter italic">JPG, PNG, WEBP (Maks 3MB)</p>
</div>
</div>
</label>
@@ -220,8 +230,8 @@
{{-- Action Button --}}
<div class="pt-4">
<button type="submit" class="w-full py-6 bg-indigo-600 text-white text-xs font-black rounded-[2.5rem] shadow-2xl shadow-indigo-100 hover:bg-indigo-700 hover:-translate-y-1 transition-all active:scale-[0.98] flex items-center justify-center gap-4 group">
<i class="fas fa-save text-xl"></i>
<span class="tracking-[0.2em] uppercase">Simpan Record Baru</span>
<i class="fas fa-save text-xl group-hover:rotate-12 transition-transform"></i>
<span class="tracking-[0.2em] uppercase">Simpan Record Baru Ilycats</span>
</button>
</div>
</form>
@@ -233,6 +243,29 @@
</style>
<script>
// Logika Sinkronisasi Searchable Datalist untuk Sire/Dam
function handleSearchableDatalist(inputId, listId, hiddenId) {
const input = document.getElementById(inputId);
const list = document.getElementById(listId);
const hidden = document.getElementById(hiddenId);
input.addEventListener('input', function() {
const options = list.options;
hidden.value = ""; // Reset hidden ID setiap kali input berubah
for (let i = 0; i < options.length; i++) {
if (options[i].value === input.value) {
hidden.value = options[i].getAttribute('data-id');
break;
}
}
});
}
handleSearchableDatalist('sire_search', 'sire_list', 'induk_jantan_id');
handleSearchableDatalist('dam_search', 'dam_list', 'induk_betina_id');
// Preview Foto
function previewImage(event) {
const reader = new FileReader();
reader.onload = function() {
+69 -36
View File
@@ -6,8 +6,8 @@
<i class="fas fa-arrow-left"></i>
</a>
<div>
<h2 class="text-2xl font-black text-slate-800 tracking-tight">Edit Profil: {{ $cat->nama_kucing }}</h2>
<p class="text-sm text-slate-500 font-medium italic uppercase tracking-tighter">ID Pasien #{{ str_pad($cat->id, 4, '0', STR_PAD_LEFT) }} • Update Identitas</p>
<h2 class="text-2xl font-black text-slate-800 tracking-tight leading-none mb-1">Edit Profil: {{ $cat->nama_kucing }}</h2>
<p class="text-[10px] text-slate-400 font-bold uppercase tracking-[0.2em]">Cattery Management • Pasien #{{ str_pad($cat->id, 4, '0', STR_PAD_LEFT) }}</p>
</div>
</div>
@@ -28,7 +28,7 @@
<form action="{{ route('cats.update', $cat->id) }}" method="POST" enctype="multipart/form-data" class="space-y-6">
@csrf
@method('PATCH')
@method('PUT')
{{-- SECTION 1: IDENTITAS UTAMA & DOKUMEN --}}
<div class="bg-white border border-slate-200 rounded-[2.5rem] p-8 shadow-sm space-y-8">
@@ -39,15 +39,14 @@
<h4 class="font-black text-slate-800 uppercase tracking-tighter text-lg">Identitas & Dokumen Resmi</h4>
</div>
<div class="flex flex-col md:flex-row gap-6 items-start">
{{-- FOTO SECTION (THUMBNAIL) --}}
<div class="flex flex-col md:flex-row gap-8 items-start">
{{-- FOTO SECTION --}}
<div class="relative group self-center md:self-start flex-shrink-0">
<div class="w-24 h-24 rounded-3xl bg-slate-50 border-2 border-slate-200 overflow-hidden ring-4 ring-indigo-50 shadow-md flex items-center justify-center">
<div class="w-28 h-28 rounded-[2rem] bg-slate-50 border-2 border-slate-200 overflow-hidden ring-8 ring-indigo-50/50 shadow-md flex items-center justify-center">
<img id="image-preview" src="{{ $cat->foto_url }}" class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110">
</div>
<label for="foto" class="absolute -bottom-2 -right-2 w-9 h-9 bg-indigo-600 text-white rounded-xl border-4 border-white cursor-pointer shadow-sm hover:scale-110 transition-transform active:scale-95 flex items-center justify-center">
<i class="fas fa-camera text-[10px]"></i>
<label for="foto" class="absolute -bottom-2 -right-2 w-10 h-10 bg-indigo-600 text-white rounded-2xl border-4 border-white cursor-pointer shadow-lg hover:bg-indigo-700 transition-all flex items-center justify-center">
<i class="fas fa-camera text-xs"></i>
<input type="file" name="foto" id="foto" class="hidden" accept="image/*" onchange="previewImage(event)">
</label>
</div>
@@ -56,32 +55,30 @@
<div class="flex-1 grid grid-cols-1 md:grid-cols-2 gap-6 w-full">
<div class="space-y-2 md:col-span-2">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Nama Lengkap Kucing</label>
<input type="text" name="nama_kucing" value="{{ old('nama_kucing', $cat->nama_kucing) }}" required class="w-full px-4 py-4 bg-slate-50 border border-slate-200 rounded-2xl text-sm font-bold text-slate-800 focus:ring-2 focus:ring-indigo-500 transition-all">
<input type="text" name="nama_kucing" value="{{ old('nama_kucing', $cat->nama_kucing) }}" required class="w-full px-5 py-4 bg-slate-50 border border-slate-200 rounded-2xl text-sm font-bold text-slate-800 focus:ring-4 focus:ring-indigo-500/10 focus:border-indigo-500 transition-all">
</div>
{{-- PERBAIKAN: GRID IDENTITAS (PEDIGREE, MICROCHIP, EMS) --}}
<div class="md:col-span-2 grid grid-cols-1 md:grid-cols-3 gap-4 border-y border-slate-50 py-6 my-2">
{{-- Input Pedigree --}}
<div class="space-y-2">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">No. Pedigree</label>
{{-- PERBAIKAN: Menghapus class uppercase --}}
<input type="text" name="pedigree" value="{{ old('pedigree', $cat->pedigree) }}" placeholder="ICA.LO.xxx"
class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl focus:ring-2 focus:ring-indigo-500 text-xs font-bold text-slate-800">
</div>
{{-- Input Microchip --}}
<div class="space-y-2">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">No. Microchip</label>
<input type="text" name="microchip" value="{{ old('microchip', $cat->microchip) }}" placeholder="9001xxxx"
class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl focus:ring-2 focus:ring-indigo-500 text-xs font-bold text-slate-800">
</div>
{{-- Input Kode EMS (Highlight Indigo) --}}
<div class="space-y-2">
<label class="text-[10px] font-black text-indigo-600 uppercase tracking-widest ml-1 flex items-center gap-2">
<i class="fas fa-dna text-[10px]"></i> Kode EMS
</label>
{{-- PERBAIKAN: Menghapus class uppercase --}}
<input type="text" name="kode_ems" value="{{ old('kode_ems', $cat->kode_ems) }}" placeholder="PER d 03"
class="w-full px-4 py-3 bg-indigo-50/30 border border-indigo-100 rounded-xl focus:ring-2 focus:ring-indigo-500 text-xs font-black text-indigo-700 uppercase">
class="w-full px-4 py-3 bg-indigo-50/30 border border-indigo-100 rounded-xl focus:ring-2 focus:ring-indigo-500 text-xs font-black text-indigo-700">
</div>
</div>
@@ -99,18 +96,18 @@
<input type="date" name="tanggal_lahir" value="{{ old('tanggal_lahir', $cat->tanggal_lahir?->format('Y-m-d')) }}" class="w-full px-4 py-4 bg-slate-50 border border-slate-200 rounded-2xl text-sm font-bold text-slate-800 focus:ring-2 focus:ring-indigo-500">
</div>
{{-- Registry / Federasi --}}
<div class="space-y-3 md:col-span-2">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Registry / Federasi</label>
<div class="grid grid-cols-2 md:grid-cols-4 gap-3">
@foreach(['ICA', 'CFA', 'WCF', 'FFF'] as $reg)
<div class="grid grid-cols-2 md:grid-cols-5 gap-3">
@foreach(['ICA', 'CFA', 'WCF', 'FFF', 'NON-PED'] as $reg)
@php
$isChecked = (is_array(old('registry')) && in_array($reg, old('registry'))) ||
(is_array($cat->registry) && in_array($reg, $cat->registry));
$isChecked = old('registry')
? in_array($reg, old('registry'))
: (is_array($cat->registry) && in_array($reg, $cat->registry));
@endphp
<label class="block cursor-pointer group">
<input type="checkbox" name="registry[]" value="{{ $reg }}" {{ $isChecked ? 'checked' : '' }} class="sr-only peer">
<div class="py-4 text-center border-2 border-slate-100 rounded-2xl text-[10px] font-black text-slate-400 peer-checked:bg-indigo-600 peer-checked:text-white peer-checked:border-indigo-600 transition-all shadow-sm group-hover:border-slate-300">
<div class="py-4 text-center border-2 border-slate-100 rounded-2xl text-[10px] font-black text-slate-400 peer-checked:bg-indigo-600 peer-checked:text-white peer-checked:border-indigo-600 transition-all shadow-sm group-hover:border-slate-300 uppercase">
{{ $reg }}
</div>
</label>
@@ -118,20 +115,19 @@
</div>
</div>
{{-- Jenis Kelamin --}}
<div class="space-y-2 md:col-span-2">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Jenis Kelamin</label>
<div class="flex gap-4">
<label class="flex-1 cursor-pointer group">
<input type="radio" name="jenis_kelamin" value="Jantan" {{ old('jenis_kelamin', $cat->jenis_kelamin) == 'Jantan' ? 'checked' : '' }} class="sr-only peer">
<div class="p-4 text-center border-2 border-slate-100 rounded-2xl text-xs font-black text-slate-400 peer-checked:bg-blue-50 peer-checked:border-blue-500 peer-checked:text-blue-600 transition-all shadow-sm group-hover:border-slate-200">
<i class="fas fa-mars mr-2"></i> JANTAN
<i class="fas fa-mars mr-2"></i> JANTAN (SIRE)
</div>
</label>
<label class="flex-1 cursor-pointer group">
<input type="radio" name="jenis_kelamin" value="Betina" {{ old('jenis_kelamin', $cat->jenis_kelamin) == 'Betina' ? 'checked' : '' }} class="sr-only peer">
<div class="p-4 text-center border-2 border-slate-100 rounded-2xl text-xs font-black text-slate-400 peer-checked:bg-pink-50 peer-checked:border-pink-500 peer-checked:text-pink-600 transition-all shadow-sm group-hover:border-slate-200">
<i class="fas fa-venus mr-2"></i> BETINA
<i class="fas fa-venus mr-2"></i> BETINA (DAM)
</div>
</label>
</div>
@@ -147,24 +143,36 @@
</h4>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
{{-- Searchable Sire --}}
<div class="space-y-2">
<label class="text-[10px] font-bold text-slate-400 uppercase ml-1">Sire (Bapak)</label>
<select name="induk_jantan_id" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-2xl text-xs font-bold text-slate-700 focus:ring-2 focus:ring-indigo-500">
<option value="">-- Tidak Diketahui --</option>
<input type="text" list="sire_list" id="sire_search"
value="{{ old('sire_search', $cat->sire?->nama_kucing) }}"
placeholder="Ketik nama sire..."
class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-2xl text-xs font-bold text-slate-700 focus:ring-2 focus:ring-indigo-500" autocomplete="off">
<datalist id="sire_list">
@foreach($sires as $sire)
<option value="{{ $sire->id }}" {{ old('induk_jantan_id', $cat->induk_jantan_id) == $sire->id ? 'selected' : '' }}>{{ $sire->nama_kucing }}</option>
<option data-id="{{ $sire->id }}" value="{{ $sire->nama_kucing }}">
@endforeach
</select>
</datalist>
<input type="hidden" name="induk_jantan_id" id="induk_jantan_id" value="{{ old('induk_jantan_id', $cat->induk_jantan_id) }}">
</div>
{{-- Searchable Dam --}}
<div class="space-y-2">
<label class="text-[10px] font-bold text-slate-400 uppercase ml-1">Dam (Ibu)</label>
<select name="induk_betina_id" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-2xl text-xs font-bold text-slate-700 focus:ring-2 focus:ring-indigo-500">
<option value="">-- Tidak Diketahui --</option>
<input type="text" list="dam_list" id="dam_search"
value="{{ old('dam_search', $cat->dam?->nama_kucing) }}"
placeholder="Ketik nama dam..."
class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-2xl text-xs font-bold text-slate-700 focus:ring-2 focus:ring-indigo-500" autocomplete="off">
<datalist id="dam_list">
@foreach($dams as $dam)
<option value="{{ $dam->id }}" {{ old('induk_betina_id', $cat->induk_betina_id) == $dam->id ? 'selected' : '' }}>{{ $dam->nama_kucing }}</option>
<option data-id="{{ $dam->id }}" value="{{ $dam->nama_kucing }}">
@endforeach
</select>
</datalist>
<input type="hidden" name="induk_betina_id" id="induk_betina_id" value="{{ old('induk_betina_id', $cat->induk_betina_id) }}">
</div>
<div class="space-y-2">
<label class="text-[10px] font-bold text-slate-400 uppercase ml-1">Lokasi Kandang</label>
<select name="lokasi_kandang" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-2xl text-sm font-black text-indigo-600 uppercase focus:ring-2 focus:ring-indigo-500">
@@ -173,6 +181,7 @@
@endforeach
</select>
</div>
<div class="space-y-2">
<label class="text-[10px] font-bold text-slate-400 uppercase ml-1">PIC Bertugas</label>
<select name="pic_id" class="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-2xl text-[11px] font-bold text-slate-700 focus:ring-2 focus:ring-indigo-500">
@@ -210,27 +219,51 @@
</h4>
<label class="text-[10px] font-bold text-slate-400 uppercase ml-1">Berat Badan</label>
<div class="relative mt-2">
<input type="number" step="0.01" name="berat_badan" value="{{ old('berat_badan', $cat->berat_badan) }}" class="w-full pl-5 pr-14 py-4 bg-slate-50 border border-slate-200 rounded-[1.5rem] text-2xl font-black text-slate-800 focus:ring-2 focus:ring-emerald-500 transition-all">
<input type="number" step="0.01" name="berat_badan" value="{{ old('berat_badan', $cat->berat_badan) }}" class="w-full pl-5 pr-14 py-4 bg-slate-50 border border-slate-200 rounded-[1.5rem] text-2xl font-black text-slate-800 focus:ring-4 focus:ring-emerald-500/10 focus:border-emerald-500 transition-all">
<span class="absolute right-5 top-1/2 -translate-y-1/2 text-xs font-black text-slate-400">KG</span>
</div>
</div>
<div class="bg-white border border-slate-200 rounded-[2.5rem] p-8 shadow-sm border-l-4 border-l-rose-500">
<label class="text-[10px] font-black text-rose-600 uppercase tracking-widest ml-1">Kondisi Kesehatan</label>
<textarea name="riwayat_sakit_terakhir" class="w-full mt-2 p-4 bg-slate-50 border border-slate-200 rounded-2xl text-xs font-bold text-slate-700 h-24 focus:ring-2 focus:ring-rose-200 transition-all">{{ old('riwayat_sakit_terakhir', $cat->riwayat_sakit_terakhir) }}</textarea>
<textarea name="riwayat_sakit_terakhir" placeholder="Ceritakan kondisi kesehatan..." class="w-full mt-2 p-4 bg-slate-50 border border-slate-200 rounded-2xl text-xs font-bold text-slate-700 h-24 focus:ring-2 focus:ring-rose-200 transition-all">{{ old('riwayat_sakit_terakhir', $cat->riwayat_sakit_terakhir) }}</textarea>
</div>
</div>
</div>
{{-- Action Button --}}
<button type="submit" class="w-full py-6 bg-indigo-600 text-white text-xs font-black rounded-[2.5rem] shadow-2xl hover:bg-indigo-700 transition-all active:scale-[0.98] flex items-center justify-center gap-4 group">
<i class="fas fa-cloud-upload-alt text-lg group-hover:animate-bounce transition-transform"></i>
<button type="submit" class="w-full py-6 bg-indigo-600 text-white text-xs font-black rounded-[2.5rem] shadow-2xl hover:bg-indigo-700 hover:shadow-indigo-200 transition-all active:scale-[0.98] flex items-center justify-center gap-4 group">
<i class="fas fa-save text-lg group-hover:rotate-12 transition-transform"></i>
<span class="tracking-[0.2em] uppercase">Simpan Perubahan Data Ilycats</span>
</button>
</form>
</div>
<script>
// Logika Sinkronisasi Searchable Datalist untuk Sire/Dam
function handleSearchableDatalist(inputId, listId, hiddenId) {
const input = document.getElementById(inputId);
const list = document.getElementById(listId);
const hidden = document.getElementById(hiddenId);
input.addEventListener('input', function() {
const options = list.options;
const val = input.value;
hidden.value = ""; // Reset hidden ID jika input tidak cocok dengan opsi apa pun
for (let i = 0; i < options.length; i++) {
if (options[i].value === val) {
hidden.value = options[i].getAttribute('data-id');
break;
}
}
});
}
handleSearchableDatalist('sire_search', 'sire_list', 'induk_jantan_id');
handleSearchableDatalist('dam_search', 'dam_list', 'induk_betina_id');
// Preview Foto saat dipilih
function previewImage(event) {
const reader = new FileReader();
const preview = document.getElementById('image-preview');
+49 -183
View File
@@ -1,185 +1,51 @@
<x-app-layout>
<div class="space-y-6 pb-8">
{{-- 1. STATS OVERVIEW --}}
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<x-stats-card title="Total Kucing" :value="$totalCats" icon="fa-cat" color="indigo" />
<x-stats-card title="Kucing Sehat" :value="$totalCats - $sickCats" icon="fa-heart" color="emerald" />
<x-stats-card title="Dalam Perawatan" :value="$sickCats" icon="fa-stethoscope" color="rose" />
</div>
{{-- 2. ACTION HEADER --}}
<div class="flex flex-col md:flex-row md:items-center justify-between gap-4">
<div>
<h2 class="text-2xl font-black text-slate-800 tracking-tight leading-none mb-1 uppercase">Manajemen Kucing</h2>
<p class="text-[10px] text-slate-400 font-bold uppercase tracking-[0.2em]">Cattery Management System • Ilycats</p>
</div>
{{-- PROTEKSI TOMBOL CREATE --}}
@can('check-access', ['cats', 'create'])
<div class="flex items-center gap-3">
<a href="{{ route('cats.create') }}" class="inline-flex items-center px-6 py-3 bg-indigo-600 text-white text-xs font-black rounded-2xl shadow-lg shadow-indigo-100 hover:bg-indigo-700 transition-all active:scale-95">
<i class="fas fa-plus-circle mr-2"></i> REGISTRASI KUCING BARU
</a>
</div>
@endcan
</div>
{{-- 3. TABLE CONTAINER --}}
<div class="bg-white border border-slate-200 rounded-[2.5rem] overflow-hidden shadow-sm">
{{-- SEARCH & QUICK FILTER --}}
<div class="p-6 bg-slate-50/50 border-b border-slate-100 flex flex-col md:flex-row justify-between gap-4">
<form action="{{ route('cats.index') }}" method="GET" class="relative w-full md:w-1/3">
<i class="fas fa-search absolute left-4 top-1/2 -translate-y-1/2 text-slate-400 text-xs"></i>
<input type="text" name="search" value="{{ request('search') }}" placeholder="Cari nama, ras, atau microchip..."
class="w-full pl-12 pr-4 py-3 bg-white border border-slate-200 rounded-xl text-xs font-bold focus:ring-2 focus:ring-indigo-500 transition-all shadow-sm">
</form>
<div class="flex items-center p-1 bg-slate-100 rounded-xl shrink-0">
<a href="{{ route('cats.index') }}" class="px-4 py-2 rounded-lg text-[10px] font-black uppercase tracking-widest {{ !request('status') ? 'bg-white text-indigo-600 shadow-sm' : 'text-slate-500 hover:text-slate-700' }}">Semua</a>
<a href="{{ route('cats.index', ['status' => 'Active']) }}" class="px-4 py-2 rounded-lg text-[10px] font-black uppercase tracking-widest {{ request('status') == 'Active' ? 'bg-white text-emerald-600 shadow-sm' : 'text-slate-500 hover:text-slate-700' }}">Dewasa</a>
<a href="{{ route('cats.index', ['status' => 'Kitten']) }}" class="px-4 py-2 rounded-lg text-[10px] font-black uppercase tracking-widest {{ request('status') == 'Kitten' ? 'bg-white text-amber-600 shadow-sm' : 'text-slate-500 hover:text-slate-700' }}">Kitten</a>
</div>
</div>
<div class="overflow-x-auto">
<table class="w-full text-left border-collapse">
<thead class="bg-slate-50 text-[10px] font-black text-slate-400 uppercase tracking-widest border-b border-slate-100">
<tr>
<th class="px-6 py-5">Informasi Kucing</th>
<th class="px-6 py-5">Usia & Silsilah</th>
<th class="px-6 py-5 text-center">Lokasi Kandang</th>
<th class="px-6 py-5 text-center">Penanggung Jawab</th>
<th class="px-6 py-5 text-center">Monitoring Berat</th>
<th class="px-6 py-5 text-right">Aksi</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100 font-medium text-slate-700">
@forelse($cats as $cat)
<tr class="hover:bg-slate-50/80 transition-all group">
<td class="px-6 py-4">
<div class="flex items-center gap-4">
<div class="relative shrink-0">
<div class="w-14 h-14 rounded-2xl bg-slate-100 overflow-hidden ring-4 ring-white shadow-sm transition-transform group-hover:scale-105">
<img src="{{ $cat->foto_url }}" class="w-full h-full object-cover">
</div>
@if($cat->status === 'Kitten')
<div class="absolute -top-1 -right-1 w-4 h-4 bg-amber-500 border-2 border-white rounded-full shadow-sm animate-pulse" title="Kitten"></div>
@endif
</div>
<div>
<div class="flex items-center gap-2 mb-1">
<a href="{{ route('cats.show', $cat->id) }}" class="text-sm font-black text-slate-800 hover:text-indigo-600 transition-colors uppercase tracking-tight">{{ $cat->nama_kucing }}</a>
{!! $cat->gender_icon !!}
</div>
<div class="flex flex-col gap-1.5">
<div class="flex items-center gap-1.5">
<span class="px-2 py-0.5 bg-indigo-50 text-indigo-500 rounded text-[9px] font-black uppercase">{{ $cat->ras }}</span>
<span class="text-slate-300">•</span>
{!! $cat->registry_badges !!}
</div>
</div>
</div>
</div>
</td>
<td class="px-6 py-4">
<div class="flex flex-col">
<span class="text-[11px] font-black text-slate-700">{{ $cat->age }}</span>
<div class="flex items-center gap-1 mt-0.5">
<i class="fas fa-birthday-cake text-[8px] text-slate-300"></i>
<span class="text-[9px] text-slate-400 font-bold italic">{{ $cat->tanggal_lahir?->format('d M Y') ?? 'N/A' }}</span>
</div>
@if($cat->induk_betina_id)
<span class="text-[8px] text-rose-400 font-bold uppercase mt-1 tracking-tighter">Dam: {{ $cat->dam->nama_kucing }}</span>
@endif
</div>
</td>
<td class="px-6 py-4 text-center">
<div class="inline-flex items-center gap-1.5 px-3 py-1.5 bg-indigo-50/50 text-indigo-600 rounded-xl text-[10px] font-black border border-indigo-100 uppercase italic">
<i class="fas fa-door-closed text-[9px]"></i>
{{ $cat->lokasi_kandang ?? 'Global' }}
</div>
</td>
<td class="px-6 py-4 text-center">
<div class="flex flex-col items-center">
<span class="text-[10px] font-black text-slate-600 uppercase tracking-tighter">{{ $cat->pic->name ?? 'System' }}</span>
<span class="text-[8px] text-slate-400 font-bold uppercase tracking-widest">In Charge</span>
</div>
</td>
<td class="px-6 py-4 text-center">
@php $isOverdue = $cat->updated_at->diffInDays(now()) >= 3; @endphp
<div class="flex flex-col items-center">
<div class="flex items-baseline gap-0.5 {{ $isOverdue ? 'text-rose-600' : 'text-emerald-600' }}">
<span class="text-sm font-black">{{ number_format($cat->berat_badan, 2) }}</span>
<span class="text-[9px] font-bold">KG</span>
</div>
@if($isOverdue)
<div class="flex items-center gap-1 mt-1 text-rose-400 animate-pulse">
<i class="fas fa-exclamation-triangle text-[8px]"></i>
<span class="text-[7px] font-black uppercase tracking-widest">Update!</span>
</div>
@endif
</div>
</td>
<td class="px-6 py-4 text-right">
<div class="flex justify-end items-center gap-2">
{{-- PROTEKSI TOMBOL READ --}}
@can('check-access', ['cats', 'read'])
<a href="{{ route('cats.show', $cat->id) }}"
class="w-9 h-9 flex items-center justify-center bg-indigo-50 text-indigo-600 rounded-xl hover:bg-indigo-600 hover:text-white transition-all shadow-sm group-hover:shadow-indigo-100"
title="Detail Medis">
<i class="fas fa-heartbeat text-xs"></i>
</a>
@endcan
{{-- PROTEKSI TOMBOL EDIT/UPDATE --}}
@can('check-access', ['cats', 'update'])
<a href="{{ route('cats.edit', $cat->id) }}"
class="w-9 h-9 flex items-center justify-center bg-amber-50 text-amber-600 rounded-xl hover:bg-amber-600 hover:text-white transition-all shadow-sm"
title="Edit Profil">
<i class="fas fa-pencil-alt text-xs"></i>
</a>
@endcan
{{-- PROTEKSI TOMBOL DELETE --}}
@can('check-access', ['cats', 'delete'])
<button type="button"
onclick="confirmDelete('delete-form-{{ $cat->id }}', '{{ $cat->nama_kucing }}')"
class="w-9 h-9 flex items-center justify-center bg-rose-50 text-rose-600 rounded-xl hover:bg-rose-500 hover:text-white transition-all shadow-sm"
title="Hapus">
<i class="fas fa-trash text-xs"></i>
</button>
<form id="delete-form-{{ $cat->id }}" action="{{ route('cats.destroy', $cat->id) }}" method="POST" class="hidden">
@csrf @method('DELETE')
</form>
@endcan
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="px-6 py-32 text-center bg-slate-50/30">
<div class="flex flex-col items-center">
<i class="fas fa-cat text-5xl text-slate-100 mb-4 animate-bounce"></i>
<h3 class="text-slate-400 font-black uppercase text-xs tracking-[0.4em]">Belum Ada Data Kucing</h3>
<p class="text-slate-300 text-[10px] font-bold mt-2 uppercase">Silakan klik tombol registrasi untuk memulai</p>
</div>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="p-8 border-t border-slate-100 bg-slate-50/30">
{{ $cats->links() }}
</div>
</div>
@php
$currentSort=request('sort','created_at'); $currentDir=request('direction','desc'); $nextDir=$currentDir==='asc'?'desc':'asc';
$sortIcon=function($field)use($currentSort,$currentDir){return $currentSort!==$field?'fa-sort text-slate-300':($currentDir==='asc'?'fa-sort-up text-indigo-600':'fa-sort-down text-indigo-600');};
@endphp
<div class="mb-6 flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
<div><h1 class="text-2xl font-bold text-slate-900">Data kucing</h1><p class="mt-1 text-sm text-slate-500">Profil, silsilah, pedigree, berat badan, dan jadwal perawatan.</p></div>
<div class="flex flex-wrap gap-2">@can('check-access',['cats','update'])<a href="{{ route('cats.bulk-weight') }}" class="border border-slate-300 bg-white px-4 py-2.5 text-sm font-semibold text-slate-700 hover:bg-slate-50"><i class="fas fa-weight-scale mr-2"></i>Input berat massal</a>@endcan @can('check-access',['cats','create'])<a href="{{ route('cats.create') }}" class="bg-indigo-600 px-4 py-2.5 text-sm font-semibold text-white hover:bg-indigo-700"><i class="fas fa-plus mr-2"></i>Tambah kucing</a>@endcan</div>
</div>
</x-app-layout>
<div class="mb-5 grid gap-3 sm:grid-cols-3">
<div class="border border-slate-200 bg-white p-4"><p class="text-xs text-slate-500">Total kucing</p><p class="mt-1 text-2xl font-bold text-slate-900">{{ $totalCats }}</p></div>
<div class="border border-slate-200 bg-white p-4"><p class="text-xs text-slate-500">Sehat</p><p class="mt-1 text-2xl font-bold text-emerald-700">{{ max(0,$totalCats-$sickCats) }}</p></div>
<div class="border border-slate-200 bg-white p-4"><p class="text-xs text-slate-500">Dalam perawatan</p><p class="mt-1 text-2xl font-bold text-rose-600">{{ $sickCats }}</p></div>
</div>
<section class="border border-slate-200 bg-white">
<div class="flex flex-col gap-3 border-b border-slate-200 p-4 lg:flex-row lg:items-center lg:justify-between">
<form method="GET" action="{{ route('cats.index') }}" class="flex w-full max-w-lg gap-2">
<input type="hidden" name="status" value="{{ request('status') }}"><input type="hidden" name="sort" value="{{ request('sort') }}"><input type="hidden" name="direction" value="{{ request('direction') }}">
<div class="relative flex-1"><i class="fas fa-search absolute left-3 top-1/2 -translate-y-1/2 text-sm text-slate-400"></i><input name="search" value="{{ request('search') }}" placeholder="Cari nama, EMS, microchip, ras, kandang..." class="field-input pl-9"></div><button class="border border-slate-300 px-4 text-sm font-semibold text-slate-700 hover:bg-slate-50">Cari</button>
</form>
<div class="flex flex-wrap gap-1 text-sm">@foreach([''=>'Semua','Dewasa'=>'Dewasa','Junior'=>'Junior','Kitten'=>'Kitten'] as $value=>$label)<a href="{{ route('cats.index',array_merge(request()->except('page','status'),$value?['status'=>$value]:[])) }}" class="px-3 py-2 {{ request('status','')===$value?'bg-slate-900 text-white':'text-slate-600 hover:bg-slate-100' }}">{{ $label }}</a>@endforeach</div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-slate-200 text-sm">
<thead class="bg-slate-50 text-left text-xs font-semibold text-slate-500"><tr>
<th class="px-4 py-3"><a class="flex items-center gap-2" href="{{ request()->fullUrlWithQuery(['sort'=>'nama_kucing','direction'=>$nextDir]) }}">Kucing <i class="fas {{ $sortIcon('nama_kucing') }}"></i></a></th>
<th class="px-4 py-3">Identitas & pedigree</th><th class="px-4 py-3">Silsilah</th>
<th class="px-4 py-3"><a class="flex items-center gap-2" href="{{ request()->fullUrlWithQuery(['sort'=>'berat_badan','direction'=>$nextDir]) }}">Berat <i class="fas {{ $sortIcon('berat_badan') }}"></i></a></th>
<th class="px-4 py-3"><a class="flex items-center gap-2" href="{{ request()->fullUrlWithQuery(['sort'=>'lokasi_kandang','direction'=>$nextDir]) }}">Kandang <i class="fas {{ $sortIcon('lokasi_kandang') }}"></i></a></th>
<th class="px-4 py-3 text-right">Aksi</th>
</tr></thead>
<tbody class="divide-y divide-slate-100">
@forelse($cats as $cat)
<tr class="hover:bg-slate-50">
<td class="px-4 py-3"><div class="flex min-w-52 items-center gap-3"><img src="{{ $cat->foto_url }}" alt="{{ $cat->nama_kucing }}" class="h-11 w-11 rounded-lg border border-slate-200 object-cover"><div><a href="{{ route('cats.show',$cat) }}" class="font-semibold text-slate-900 hover:text-indigo-600">{{ $cat->nama_kucing }}</a><p class="mt-0.5 text-xs text-slate-500">{{ $cat->jenis_kelamin }} · {{ $cat->ras }}</p></div></div></td>
<td class="px-4 py-3"><div class="space-y-1"><p class="text-xs text-slate-600"><span class="text-slate-400">EMS:</span> {{ $cat->kode_ems ?: '-' }}</p><p class="text-xs text-slate-600"><span class="text-slate-400">Microchip:</span> {{ $cat->microchip ?: '-' }}</p><div class="flex flex-wrap gap-1">@forelse($cat->registrations as $reg)<span class="border border-slate-200 bg-slate-50 px-1.5 py-0.5 text-[11px] font-semibold text-slate-600">{{ $reg->association->code }}{{ $reg->is_primary?' · utama':'' }}</span>@empty<span class="text-xs text-slate-400">Belum ada registrasi</span>@endforelse</div></div></td>
<td class="px-4 py-3"><p class="text-xs text-slate-600">{{ $cat->age }}</p><p class="mt-1 text-xs text-slate-500">Jantan: {{ $cat->sire->nama_kucing ?? '-' }}</p><p class="text-xs text-slate-500">Betina: {{ $cat->dam->nama_kucing ?? '-' }}</p></td>
<td class="px-4 py-3"><p class="font-semibold text-slate-800">{{ number_format((float)($cat->berat_badan ?? $cat->berat_terakhir ?? 0),2) }} kg</p><p class="text-xs {{ $cat->treatment_status==1?'text-rose-600':'text-emerald-600' }}">{{ $cat->treatment_status==1?'Dalam perawatan':'Sehat' }}</p></td>
<td class="px-4 py-3"><p class="text-slate-700">{{ $cat->lokasi_kandang ?: '-' }}</p><p class="text-xs text-slate-500">{{ $cat->pic->name ?? '-' }}</p></td>
<td class="px-4 py-3"><div class="flex justify-end gap-1"><a href="{{ route('cats.show',$cat) }}" class="p-2 text-slate-500 hover:bg-slate-100" title="Lihat"><i class="fas fa-eye"></i></a><a href="{{ route('cats.pedigree',$cat) }}" class="p-2 text-slate-500 hover:bg-slate-100" title="Pedigree"><i class="fas fa-file-lines"></i></a>@can('check-access',['cats','update'])<a href="{{ route('cats.edit',$cat) }}" class="p-2 text-slate-500 hover:bg-slate-100" title="Ubah"><i class="fas fa-pen"></i></a>@endcan @can('check-access',['cats','delete'])<form id="delete-cat-{{ $cat->id }}" method="POST" action="{{ route('cats.destroy',$cat) }}">@csrf @method('DELETE')<button type="button" onclick="confirmDelete('delete-cat-{{ $cat->id }}','{{ addslashes($cat->nama_kucing) }}')" class="p-2 text-rose-500 hover:bg-rose-50" title="Hapus"><i class="fas fa-trash"></i></button></form>@endcan</div></td>
</tr>
@empty<tr><td colspan="6" class="px-4 py-12 text-center text-sm text-slate-500">Data kucing tidak ditemukan.</td></tr>@endforelse
</tbody>
</table>
</div>
<div class="border-t border-slate-200 p-4">{{ $cats->links() }}</div>
</section>
</x-app-layout>
@@ -0,0 +1,335 @@
<x-app-layout>
<div class="max-w-[1600px] mx-auto space-y-8 pb-12">
{{-- Header Section --}}
<div class="flex items-center gap-4 px-2">
<a href="{{ route('cats.index') }}" class="p-3 bg-white border border-slate-200 rounded-2xl text-slate-400 hover:text-indigo-600 transition-all shadow-sm active:scale-90">
<i class="fas fa-arrow-left"></i>
</a>
<div>
<h2 class="text-3xl font-black text-slate-800 tracking-tight leading-none">Bulk Perawatan Manager</h2>
<p class="text-sm text-slate-500 font-medium italic uppercase tracking-widest mt-1">Manajemen Tindakan Medis Masal • Ily Cattery</p>
</div>
</div>
<form action="{{ route('medical-records.bulk.store') }}" method="POST">
@csrf
<div class="grid grid-cols-1 xl:grid-cols-12 gap-8 px-2">
{{-- KIRI: Pemilihan Kucing --}}
<div class="lg:col-span-5 space-y-6">
<div x-data="catSelector()" class="bg-white border border-slate-200 rounded-[3rem] p-8 shadow-sm h-full flex flex-col relative overflow-hidden">
<div class="flex items-center justify-between mb-6">
<div class="flex items-center gap-3">
<h4 class="font-black text-slate-800 uppercase tracking-tighter text-lg">Pilih Kucing</h4>
<div x-show="selectedCount > 0" x-transition x-cloak class="flex items-center">
<span class="bg-indigo-100 text-indigo-700 text-[10px] font-black px-2.5 py-1 rounded-lg uppercase tracking-widest border border-indigo-200 shadow-sm">
<span x-text="selectedCount"></span> Terpilih
</span>
</div>
</div>
<div class="flex items-center gap-2">
<input type="checkbox" id="select_all" x-model="selectAll" @change="toggleAll()" class="w-4 h-4 text-indigo-600 border-slate-300 rounded focus:ring-indigo-500 cursor-pointer">
<label for="select_all" class="text-[10px] font-black text-slate-400 uppercase tracking-widest cursor-pointer hover:text-indigo-600 transition-colors">Pilih Semua</label>
</div>
</div>
{{-- Search Filter Kucing --}}
<div class="relative mb-6">
<i class="fas fa-search absolute left-4 top-1/2 -translate-y-1/2 text-slate-400 text-xs"></i>
<input type="text" x-model="search" @input="resetPage()" placeholder="Cari nama atau kode kucing..." class="w-full pl-11 pr-4 py-3.5 bg-slate-50 border border-slate-200 rounded-2xl text-xs font-bold focus:ring-4 focus:ring-indigo-500/10 outline-none transition-all placeholder:text-slate-400">
</div>
{{-- List Kucing (Paginated) --}}
<div class="flex-1 overflow-y-auto custom-scrollbar pr-2 space-y-3" style="max-height: 450px;">
<template x-for="cat in paginatedCats" :key="cat.id">
<label class="flex items-center gap-4 p-4 rounded-3xl border transition-all cursor-pointer group"
:class="selectedCats.includes(cat.id.toString()) ? 'border-indigo-400 bg-indigo-50/80 ring-1 ring-indigo-400 shadow-md' : 'border-slate-100 bg-slate-50/50 hover:bg-indigo-50 hover:border-indigo-100'">
<input type="checkbox" name="cat_ids[]" :value="cat.id" x-model="selectedCats" @change="updateSelectAll()" class="cat-checkbox w-5 h-5 text-indigo-600 border-slate-300 rounded-lg focus:ring-indigo-500 transition-all cursor-pointer">
<div class="w-12 h-12 rounded-2xl overflow-hidden border-2 shadow-sm shrink-0" :class="selectedCats.includes(cat.id.toString()) ? 'border-indigo-200' : 'border-white'">
<img :src="cat.foto_url" class="w-full h-full object-cover">
</div>
<div class="min-w-0 flex-1">
<p class="text-sm font-black uppercase truncate leading-none mb-1 transition-colors" :class="selectedCats.includes(cat.id.toString()) ? 'text-indigo-900' : 'text-slate-800'" x-text="cat.nama_kucing"></p>
<span class="text-[8px] font-black text-slate-400 uppercase tracking-widest" x-text="`${cat.ras} • ${cat.lokasi_kandang || 'Global'}`"></span>
</div>
<div class="text-right">
<span class="px-2 py-1 bg-white border border-slate-100 rounded-lg text-[8px] font-black text-slate-400 uppercase" x-text="`#${cat.id}`"></span>
</div>
</label>
</template>
<div x-show="paginatedCats.length === 0" x-cloak class="py-10 text-center text-slate-400">
<i class="fas fa-folder-open text-3xl mb-3 opacity-50"></i>
<p class="text-xs font-bold uppercase tracking-widest">Tidak ada kucing ditemukan</p>
</div>
</div>
{{-- Pagination Controls --}}
<div class="mt-6 pt-4 border-t border-slate-100 flex items-center justify-between" x-show="totalPages > 1" x-cloak>
<button type="button" @click="prevPage()" :disabled="currentPage === 1" class="p-2 bg-slate-50 text-slate-400 rounded-xl hover:bg-indigo-50 hover:text-indigo-600 disabled:opacity-50 disabled:cursor-not-allowed transition-all">
<i class="fas fa-chevron-left text-xs"></i>
</button>
<span class="text-[10px] font-black text-slate-400 uppercase tracking-widest">
Halaman <span class="text-indigo-600" x-text="currentPage"></span> dari <span x-text="totalPages"></span>
</span>
<button type="button" @click="nextPage()" :disabled="currentPage === totalPages" class="p-2 bg-slate-50 text-slate-400 rounded-xl hover:bg-indigo-50 hover:text-indigo-600 disabled:opacity-50 disabled:cursor-not-allowed transition-all">
<i class="fas fa-chevron-right text-xs"></i>
</button>
</div>
</div>
</div>
{{-- KANAN: Konfigurasi Tindakan --}}
<div class="lg:col-span-7 space-y-6">
<div class="bg-indigo-600 rounded-[3rem] p-10 text-white shadow-xl shadow-indigo-100 relative overflow-hidden h-full flex flex-col justify-between">
<div class="relative z-10 space-y-8">
<div>
<h3 class="text-2xl font-black uppercase tracking-tight">Perawatan Configuration</h3>
<p class="text-indigo-100 text-xs font-bold italic tracking-tighter uppercase">Terapkan tindakan & potong stok otomatis</p>
</div>
<div class="space-y-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="space-y-2">
<label class="text-[10px] font-black text-indigo-200 uppercase ml-1 tracking-widest">Jenis Tindakan</label>
<select name="type" id="type_selector" onchange="adjustBulkForm()" required class="w-full px-5 py-4 bg-white/10 border border-white/20 rounded-2xl text-xs font-black text-white focus:ring-4 focus:ring-white/10 outline-none appearance-none cursor-pointer">
<option value="Vaccine" class="text-slate-800">Vaksinasi</option>
<option value="Deworming" class="text-slate-800">Obat Cacing</option>
<option value="Flea Perawatan" class="text-slate-800">Obat Kutu</option>
<option value="Grooming" class="text-slate-800">Grooming (Tanpa Obat)</option>
<option value="Medis Checkup" class="text-slate-800">Medis Checkup (Multi-Obat)</option>
</select>
</div>
<div class="space-y-2">
<label class="text-[10px] font-black text-indigo-200 uppercase ml-1 tracking-widest">Tanggal Pemberian</label>
<input type="date" name="date_given" value="{{ date('Y-m-d') }}" required class="w-full px-5 py-4 bg-white/10 border border-white/20 rounded-2xl text-xs font-black text-white">
</div>
</div>
{{-- Container Obat Dinamis --}}
<div id="medicine_container" class="space-y-4">
<div class="medicine-row grid grid-cols-1 md:grid-cols-7 gap-4 p-6 bg-white/5 rounded-[2.5rem] border border-white/10 relative">
<div class="md:col-span-3 space-y-2">
<label class="text-[9px] font-black text-indigo-200 uppercase">Nama Produk</label>
{{-- PERBAIKAN: Tambahkan onchange event ke select --}}
<select name="medicines[0][name]" onchange="updateObatDetails(this)" required class="medicine-name-input w-full px-4 py-3 bg-white text-slate-800 border-none rounded-xl text-xs font-black cursor-pointer focus:ring-4 focus:ring-indigo-500/30 outline-none">
<option value="" disabled selected>-- Pilih Obat / Vitamin --</option>
@foreach($availableObats as $med)
<option value="{{ $med->nama_obat }}">{{ $med->nama_obat }} (Sisa: {{ (float)$med->qty }} {{ $med->unit }})</option>
@endforeach
</select>
</div>
<div class="md:col-span-2 space-y-2">
<label class="text-[9px] font-black text-indigo-200 uppercase">Dosis (Per Kucing)</label>
{{-- Tambahkan class 'dosage-input' --}}
<input type="text" name="medicines[0][dosage]" placeholder="Cth: 1 atau 1/2" required class="dosage-input w-full px-4 py-3 bg-white text-slate-800 border-none rounded-xl text-xs font-black">
</div>
<div class="md:col-span-2 space-y-2">
<label class="text-[9px] font-black text-indigo-200 uppercase">Satuan</label>
<input type="text" name="medicines[0][unit]" placeholder="-" readonly class="unit-display w-full px-4 py-3 bg-indigo-500/30 text-indigo-100 border border-white/10 rounded-xl text-[10px] font-black uppercase">
</div>
</div>
</div>
<button type="button" id="add_med_btn" onclick="addBulkObatRow()" class="hidden items-center gap-2 text-[10px] font-black text-white uppercase tracking-widest hover:text-indigo-200 transition-all cursor-pointer">
<i class="fas fa-plus-circle"></i> Tambah Obat Lain
</button>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="space-y-2">
<label class="text-[10px] font-black text-indigo-200 uppercase ml-1 tracking-widest">Rencana Selanjutnya</label>
<input type="date" name="next_schedule" class="w-full px-5 py-4 bg-white/10 border border-white/20 rounded-2xl text-xs font-black text-white">
</div>
<div class="space-y-2">
<label class="text-[10px] font-black text-indigo-200 uppercase ml-1 tracking-widest">Catatan (Notes)</label>
<textarea name="notes" placeholder="Berlaku untuk semua kucing yang dipilih..." class="w-full px-5 py-4 bg-white/10 border border-white/20 rounded-2xl text-xs font-black text-white h-14 outline-none focus:ring-4 focus:ring-white/10"></textarea>
</div>
</div>
</div>
</div>
<div class="relative z-10 mt-8">
<button type="submit" class="w-full py-6 bg-white text-indigo-600 font-black rounded-[2rem] text-xs uppercase tracking-[0.4em] shadow-2xl hover:scale-[1.02] transition-all active:scale-95">
APPLY TO SELECTED CATS
</button>
</div>
<i class="fas fa-heartbeat absolute -bottom-10 -left-10 text-[15rem] text-white/5"></i>
</div>
</div>
</div>
</form>
</div>
@push('scripts')
@php
// Mengolah data kucing agar aman untuk dibaca oleh AlpineJS
$catData = $cats->map(function($cat) {
return [
'id' => $cat->id,
'nama_kucing' => $cat->nama_kucing,
'ras' => $cat->ras,
'lokasi_kandang' => $cat->lokasi_kandang,
'foto_url' => $cat->foto_url
];
})->values()->toArray();
@endphp
<script>
// Data Global untuk Javascript
const allCatsData = @json($catData);
const availableMeds = @json($availableObats);
// ALPINE JS COMPONENT: Penanganan Pilih Kucing & Pagination
document.addEventListener('alpine:init', () => {
Alpine.data('catSelector', () => ({
search: '',
currentPage: 1,
itemsPerPage: 10,
selectedCats: [],
selectAll: false,
allCats: allCatsData,
get filteredCats() {
if (this.search === '') return this.allCats;
const term = this.search.toLowerCase();
return this.allCats.filter(cat =>
cat.nama_kucing.toLowerCase().includes(term) ||
(cat.lokasi_kandang && cat.lokasi_kandang.toLowerCase().includes(term))
);
},
get totalPages() { return Math.ceil(this.filteredCats.length / this.itemsPerPage) || 1; },
get paginatedCats() {
const start = (this.currentPage - 1) * this.itemsPerPage;
return this.filteredCats.slice(start, start + this.itemsPerPage);
},
get selectedCount() { return this.selectedCats.length; },
nextPage() { if (this.currentPage < this.totalPages) this.currentPage++; },
prevPage() { if (this.currentPage > 1) this.currentPage--; },
resetPage() {
this.currentPage = 1;
this.updateSelectAll();
},
toggleAll() {
if (this.selectAll) {
const currentVisibleIds = this.filteredCats.map(c => c.id.toString());
currentVisibleIds.forEach(id => {
if (!this.selectedCats.includes(id)) { this.selectedCats.push(id); }
});
} else {
const currentVisibleIds = this.filteredCats.map(c => c.id.toString());
this.selectedCats = this.selectedCats.filter(id => !currentVisibleIds.includes(id));
}
},
updateSelectAll() {
if (this.filteredCats.length === 0) {
this.selectAll = false;
return;
}
const currentVisibleIds = this.filteredCats.map(c => c.id.toString());
this.selectAll = currentVisibleIds.every(id => this.selectedCats.includes(id));
}
}));
});
// ---------------------------------------------------------
// LOGIKA FORM OBAT (AUTO-READ SATUAN DARI DATABASE)
// ---------------------------------------------------------
let medRowCount = 1;
// HTML untuk opsi select baru (Tambah Obat Lain)
const medOptionsHtml = `<option value="" disabled selected>-- Pilih Obat / Vitamin --</option>` +
availableMeds.map(med => `<option value="${med.nama_obat}">${med.nama_obat} (Sisa: ${parseFloat(med.qty)} ${med.unit})</option>`).join('');
// 1. FUNGSI MENARIK SATUAN OTOMATIS SAAT OBAT DIPILIH
function updateObatDetails(selectElement) {
const row = selectElement.closest('.medicine-row');
const unitInput = row.querySelector('.unit-display');
const selectedName = selectElement.value;
// Cari data obat dari array database
const medicine = availableMeds.find(m => m.nama_obat === selectedName);
if (medicine) {
// Tuliskan langsung satuannya (Misal: Botol, ML, PCS)
unitInput.value = medicine.unit;
} else {
unitInput.value = '-';
}
}
// 2. FUNGSI TAMPIL / SEMBUNYI FORM
function adjustBulkForm() {
const type = document.getElementById('type_selector').value;
const container = document.getElementById('medicine_container');
const addBtn = document.getElementById('add_med_btn');
const medInputs = document.querySelectorAll('.medicine-name-input');
container.classList.remove('hidden');
addBtn.classList.add('hidden');
if (type === 'Grooming') {
container.classList.add('hidden');
medInputs.forEach(i => i.required = false);
} else {
container.classList.remove('hidden');
medInputs.forEach(i => i.required = true);
if (type === 'Medis Checkup') {
addBtn.classList.remove('hidden');
}
}
}
function updateBulkUnits(val) {
document.querySelectorAll('.unit-display').forEach(u => u.value = val);
}
// 3. FUNGSI TAMBAH BARIS OBAT BARU
function addBulkObatRow() {
const container = document.getElementById('medicine_container');
const row = document.createElement('div');
row.className = 'medicine-row grid grid-cols-1 md:grid-cols-7 gap-4 p-6 bg-white/10 rounded-[2.5rem] border border-white/5 mt-4 relative';
row.innerHTML = `
<div class="md:col-span-3 space-y-2">
<select name="medicines[${medRowCount}][name]" onchange="updateObatDetails(this)" required class="medicine-name-input w-full px-4 py-3 bg-white text-slate-800 border-none rounded-xl text-xs font-black cursor-pointer focus:ring-4 focus:ring-indigo-500/30 outline-none">
${medOptionsHtml}
</select>
</div>
<div class="md:col-span-2 space-y-2">
<input type="text" name="medicines[${medRowCount}][dosage]" placeholder="Cth: 1 atau 1/2" required class="w-full px-4 py-3 bg-white text-slate-800 border-none rounded-xl text-xs font-black">
</div>
<div class="md:col-span-2 flex items-center gap-2">
<input type="text" name="medicines[${medRowCount}][unit]" placeholder="-" value="" readonly class="unit-display w-full px-4 py-3 bg-indigo-500/30 text-indigo-100 border border-white/10 rounded-xl text-[10px] font-black uppercase">
<button type="button" onclick="this.parentElement.parentElement.remove()" class="text-white hover:text-rose-200 transition-colors"><i class="fas fa-times-circle text-lg"></i></button>
</div>
`;
container.appendChild(row);
medRowCount++;
}
// Saat halaman pertama kali dimuat
document.addEventListener('DOMContentLoaded', () => {
adjustBulkForm();
// Kosongkan semua satuan default bawaan browser jika ada
document.querySelectorAll('.unit-display').forEach(u => u.value = '');
});
</script>
@endpush
</x-app-layout>
@@ -0,0 +1,152 @@
<x-app-layout>
<div class="max-w-3xl mx-auto py-12 px-4">
{{-- Header --}}
<div class="flex items-center gap-6 mb-10">
<a href="{{ route('cats.show', $cat->id) }}" class="p-4 bg-white border border-slate-200 rounded-2xl text-slate-400 hover:text-indigo-600 transition-all shadow-sm">
<i class="fas fa-arrow-left"></i>
</a>
<div>
<h2 class="text-2xl font-black text-slate-800 uppercase tracking-tight">Add Routine Ledger</h2>
<p class="text-sm text-slate-400 font-bold uppercase tracking-widest">Logging for: {{ $cat->nama_kucing }}</p>
</div>
</div>
{{-- Form Card --}}
<div class="bg-white rounded-[3rem] shadow-xl border border-slate-100 overflow-hidden">
<div class="p-10">
<form action="{{ route('medical-records.store') }}" method="POST" class="space-y-8">
@csrf
<input type="hidden" name="cat_id" value="{{ $cat->id }}">
{{-- Jenis Tindakan (Tanpa Pengobatan Umum) --}}
<div class="space-y-3">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-2">Jenis Tindakan</label>
<select name="type" id="type_selector" onchange="adjustMedisForm()" class="w-full px-6 py-5 bg-slate-50 border-none rounded-3xl text-sm font-black text-slate-800 focus:ring-4 focus:ring-indigo-500/10 transition-all cursor-pointer">
<option value="Vaccine">Vaksinasi</option>
<option value="Deworming">Obat Cacing</option>
<option value="Flea Perawatan">Obat Kutu</option>
<option value="Grooming">Grooming</option>
</select>
</div>
{{-- Obat Container --}}
<div id="medicine_container" class="space-y-4">
<div class="medicine-row p-6 bg-slate-50 rounded-[2.5rem] border border-slate-100 space-y-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 medicine-row-inner">
<div class="space-y-2">
<label class="text-[9px] font-black text-slate-400 uppercase ml-2">Produk/Obat</label>
{{-- oninput dan onchange digunakan agar auto-fill langsung jalan --}}
<input type="text" name="medicines[0][name]" id="med_name_input" list="medicine-list" required
oninput="autoFillObat(this)"
onchange="autoFillObat(this)"
class="medicine-name-input w-full px-5 py-4 border-none rounded-2xl text-xs font-black bg-white shadow-sm focus:ring-4 focus:ring-indigo-500/10" placeholder="Ketik atau pilih obat...">
</div>
<div class="grid grid-cols-2 gap-4">
<div class="space-y-2">
<label class="text-[9px] font-black text-slate-400 uppercase ml-2">Dosis</label>
<input type="text" name="medicines[0][dosage]" id="med_dosage_input" placeholder="e.g. 1/2 atau 1" required
class="dosage-input w-full px-5 py-4 border-none rounded-2xl text-xs font-black bg-white shadow-sm focus:ring-4 focus:ring-indigo-500/10">
</div>
<div class="space-y-2">
<label class="text-[9px] font-black text-slate-400 uppercase ml-2">Satuan</label>
<input type="text" name="medicines[0][unit]" id="med_unit_input" readonly
class="unit-display w-full px-5 py-4 bg-slate-100 border-none rounded-2xl text-[10px] font-black text-slate-400 cursor-not-allowed outline-none">
</div>
</div>
</div>
</div>
</div>
{{-- Tanggal --}}
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<div class="space-y-3">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-2">Tanggal Tindakan</label>
<input type="date" name="date_given" value="{{ date('Y-m-d') }}" required class="w-full px-6 py-5 bg-slate-50 border-none rounded-3xl text-sm font-black focus:ring-4 focus:ring-indigo-500/10">
</div>
<div class="space-y-3">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-2">Jadwal Berikutnya</label>
<input type="date" name="next_schedule" class="w-full px-6 py-5 bg-slate-50 border-none rounded-3xl text-sm font-black focus:ring-4 focus:ring-indigo-500/10">
</div>
</div>
<div class="space-y-3">
<label class="text-[10px] font-black text-slate-400 uppercase tracking-widest ml-2">Notes</label>
<textarea name="notes" placeholder="Catatan opsional..." class="w-full px-6 py-5 bg-slate-50 border-none rounded-3xl text-sm font-bold h-32 focus:ring-4 focus:ring-indigo-500/10"></textarea>
</div>
<button type="submit" class="w-full py-6 bg-indigo-600 text-white rounded-[2rem] font-black uppercase text-xs tracking-[0.3em] shadow-2xl shadow-indigo-200 hover:bg-indigo-700 transition-all transform active:scale-95">
Confirm & Log Routine Ledger
</button>
</form>
</div>
</div>
</div>
{{-- Datalist dibersihkan agar hanya muncul Nama Obat --}}
<datalist id="medicine-list">
@foreach($availableObats as $med)
<option value="{{ $med->nama_obat }}"></option>
@endforeach
</datalist>
@push('scripts')
<script>
// 1. Tarik Data Master Obat dari Database ke JavaScript
const masterObatData = {!! json_encode($availableObats) !!};
// 2. Tampilkan/Sembunyikan Form Obat berdasarkan "Jenis Tindakan"
function adjustMedisForm() {
const type = document.getElementById('type_selector').value;
const container = document.getElementById('medicine_container');
const nameInput = document.getElementById('med_name_input');
const dosageInput = document.getElementById('med_dosage_input');
const unitInput = document.getElementById('med_unit_input');
if (type === 'Grooming') {
// Grooming tidak butuh obat
container.style.display = 'none';
nameInput.required = false;
dosageInput.required = false;
} else {
container.style.display = 'block';
nameInput.required = true;
dosageInput.required = true;
// Jika nama obat masih kosong, set satuan default berdasarkan jenis tindakan
const fallbackUnit = { 'Vaccine': 'PCS', 'Deworming': 'TABLET', 'Flea Perawatan': 'ML' };
if (nameInput.value === '') {
unitInput.value = fallbackUnit[type] || 'PCS';
}
}
}
// 3. Fungsi Cerdas: Auto-Fill Dosis dan Satuan
function autoFillObat(inputElement) {
const row = inputElement.closest('.medicine-row-inner');
const unitInput = row.querySelector('.unit-display');
const dosageInput = row.querySelector('.dosage-input');
// Cari kecocokan nama obat dengan data master (Tidak sensitif huruf besar/kecil)
const selectedObat = masterObatData.find(med => med.nama_obat.toLowerCase() === inputElement.value.toLowerCase());
if (selectedObat) {
// Jika obat terdaftar di database, ambil satuannya!
unitInput.value = selectedObat.unit;
// Beri nilai otomatis "1" pada dosis jika masih kosong untuk mempercepat input
if (!dosageInput.value) {
dosageInput.value = '1';
}
} else {
// Jika obat diketik manual (tidak ada di database), kembalikan ke satuan default
const type = document.getElementById('type_selector').value;
const fallbackUnit = { 'Vaccine': 'PCS', 'Deworming': 'TABLET', 'Flea Perawatan': 'ML' };
unitInput.value = fallbackUnit[type] || 'PCS';
}
}
// Jalankan saat halaman pertama kali dimuat
document.addEventListener('DOMContentLoaded', adjustMedisForm);
</script>
@endpush
</x-app-layout>
@@ -139,11 +139,11 @@
{{-- FIX: Base64 SVG yang sudah Anda buat di Controller --}}
<img src="data:image/svg+xml;base64,{{ $qrCode }}" width="90">
</div>
<div class="qr-text">Scan Medical History</div>
<div class="qr-text">Scan Medis History</div>
</div>
<div class="footer">
Generated by ILY Cattery Management System<br>
Generated by ILY Cattery Management Sistem<br>
{{ now()->format('d M Y H:i') }}
</div>
</div>
@@ -0,0 +1,51 @@
<x-app-layout>
<div class="mb-6 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<div><a href="{{ route('cats.show',$cat) }}" class="mb-2 inline-flex items-center gap-2 text-sm text-slate-500 hover:text-slate-800"><i class="fas fa-arrow-left"></i>Kembali ke profil</a><h1 class="text-2xl font-bold text-slate-900">Registrasi & pedigree</h1><p class="mt-1 text-sm text-slate-500">{{ $cat->nama_kucing }} dapat memiliki registrasi dan sertifikat dari lebih dari satu asosiasi.</p></div>
</div>
<div class="grid gap-6 xl:grid-cols-[1fr_360px]">
<div class="space-y-4">
@forelse($cat->registrations as $registration)
<section class="border border-slate-200 bg-white">
<div class="flex flex-wrap items-start justify-between gap-3 border-b border-slate-200 px-5 py-4">
<div class="flex items-center gap-3"><div class="flex h-10 min-w-10 items-center justify-center bg-slate-100 px-2 text-sm font-bold text-slate-700">{{ $registration->association->code }}</div><div><h2 class="font-semibold text-slate-900">{{ $registration->association->name }}</h2><p class="text-xs text-slate-500">{{ $registration->is_primary ? 'Pedigree utama' : 'Registrasi tambahan' }}</p></div></div>
<form action="{{ route('cats.registrations.destroy',[$cat,$registration]) }}" method="POST" onsubmit="return confirm('Hapus registrasi ini beserta dokumennya?')">@csrf @method('DELETE')<button class="text-sm font-medium text-rose-600 hover:text-rose-700">Hapus</button></form>
</div>
<form action="{{ route('cats.registrations.update',[$cat,$registration]) }}" method="POST" class="grid gap-4 p-5 sm:grid-cols-2 lg:grid-cols-3">@csrf @method('PUT')
<div><label class="field-label">Nomor registrasi</label><input name="registration_number" value="{{ $registration->registration_number }}" class="field-input"></div>
<div><label class="field-label">Nomor pedigree</label><input name="pedigree_number" value="{{ $registration->pedigree_number }}" class="field-input"></div>
<div><label class="field-label">Nomor sertifikat</label><input name="certificate_number" value="{{ $registration->certificate_number }}" class="field-input"></div>
<div><label class="field-label">Tanggal terbit</label><input type="date" name="issue_date" value="{{ $registration->issue_date?->format('Y-m-d') }}" class="field-input"></div>
<div><label class="field-label">Gelar / title</label><input name="title" value="{{ $registration->title }}" class="field-input" placeholder="Contoh: CH, GCH"></div>
<div><label class="field-label">Status kepemilikan</label><select name="ownership_status" class="field-input"><option value="">-</option>@foreach(['milik_sendiri'=>'Milik sendiri','co_own'=>'Co-own','transfer'=>'Transfer','lainnya'=>'Lainnya'] as $v=>$l)<option value="{{ $v }}" @selected($registration->ownership_status===$v)>{{ $l }}</option>@endforeach</select></div>
<div class="sm:col-span-2 lg:col-span-3"><label class="field-label">Catatan</label><textarea name="notes" rows="2" class="field-input">{{ $registration->notes }}</textarea></div>
<label class="flex items-center gap-2 text-sm text-slate-700"><input type="hidden" name="is_primary" value="0"><input type="checkbox" name="is_primary" value="1" @checked($registration->is_primary) class="rounded border-slate-300 text-indigo-600">Jadikan pedigree utama</label>
<div class="sm:col-span-2 flex justify-end"><button class="border border-slate-300 bg-white px-4 py-2 text-sm font-semibold text-slate-700 hover:bg-slate-50">Simpan perubahan</button></div>
</form>
<div class="border-t border-slate-200 p-5">
<div class="mb-3 flex items-center justify-between"><h3 class="text-sm font-semibold text-slate-800">Dokumen</h3><span class="text-xs text-slate-500">PDF/JPG/PNG, maks. 10 MB</span></div>
<div class="mb-4 grid gap-2">@forelse($registration->documents as $document)<div class="flex items-center justify-between gap-3 border border-slate-200 p-3"><div class="min-w-0"><a href="{{ Storage::url($document->file_path) }}" target="_blank" class="truncate text-sm font-medium text-indigo-600 hover:underline">{{ $document->label }}</a><p class="text-xs text-slate-500">{{ ucfirst($document->document_type) }}{{ $document->issued_at ? ' · '.$document->issued_at->format('d-m-Y') : '' }}</p></div><form action="{{ route('cats.registrations.documents.destroy',[$cat,$registration,$document]) }}" method="POST">@csrf @method('DELETE')<button class="text-xs font-medium text-rose-600">Hapus</button></form></div>@empty<p class="text-sm text-slate-500">Belum ada dokumen pada registrasi ini.</p>@endforelse</div>
<form action="{{ route('cats.registrations.documents.store',[$cat,$registration]) }}" method="POST" enctype="multipart/form-data" class="grid gap-3 md:grid-cols-[1fr_180px_180px_auto]">@csrf<input type="file" name="document" required class="field-input py-2"><select name="document_type" class="field-input"><option value="pedigree">Pedigree</option><option value="registration">Registrasi</option><option value="ownership">Kepemilikan</option><option value="title">Gelar</option><option value="other">Lainnya</option></select><input name="label" class="field-input" placeholder="Nama dokumen"><button class="bg-slate-800 px-4 py-2 text-sm font-semibold text-white hover:bg-slate-900">Tambah dokumen</button></form>
</div>
</section>
@empty
<div class="border border-dashed border-slate-300 bg-white p-10 text-center"><i class="fas fa-file-lines mb-3 text-3xl text-slate-300"></i><p class="font-medium text-slate-700">Belum ada registrasi pedigree</p><p class="mt-1 text-sm text-slate-500">Tambahkan asosiasi dari formulir di sebelah kanan.</p></div>
@endforelse
</div>
<aside class="h-fit border border-slate-200 bg-white p-5" x-data="{custom:false}">
<h2 class="font-semibold text-slate-900">Tambah registrasi</h2><p class="mt-1 text-sm text-slate-500">Satu asosiasi dapat ditambahkan satu kali untuk setiap kucing.</p>
<form action="{{ route('cats.registrations.store',$cat) }}" method="POST" enctype="multipart/form-data" class="mt-5 space-y-4">@csrf
<div><label class="field-label">Asosiasi</label><select name="association_id" required class="field-input" @change="custom=$event.target.value==='custom'"><option value="">Pilih asosiasi</option>@foreach($associations as $association)<option value="{{ $association->id }}">{{ $association->code }} - {{ $association->name }}</option>@endforeach<option value="custom">Asosiasi lain…</option></select></div>
<template x-if="custom"><div class="space-y-3"><div><label class="field-label">Kode asosiasi</label><input name="association_code" class="field-input" placeholder="Contoh: TICA"></div><div><label class="field-label">Nama asosiasi</label><input name="association_name" class="field-input"></div></div></template>
<div><label class="field-label">Nomor registrasi</label><input name="registration_number" class="field-input"></div>
<div><label class="field-label">Nomor pedigree</label><input name="pedigree_number" class="field-input"></div>
<div><label class="field-label">Nomor sertifikat</label><input name="certificate_number" class="field-input"></div>
<div class="grid grid-cols-2 gap-3"><div><label class="field-label">Tanggal terbit</label><input type="date" name="issue_date" class="field-input"></div><div><label class="field-label">Gelar</label><input name="title" class="field-input"></div></div>
<div><label class="field-label">File sertifikat</label><input type="file" name="certificate_file" accept=".pdf,.jpg,.jpeg,.png" class="field-input py-2"></div>
<label class="flex items-center gap-2 text-sm text-slate-700"><input type="hidden" name="is_primary" value="0"><input type="checkbox" name="is_primary" value="1" class="rounded border-slate-300 text-indigo-600">Jadikan pedigree utama</label>
<button class="w-full bg-indigo-600 px-4 py-2.5 text-sm font-semibold text-white hover:bg-indigo-700">Simpan registrasi</button>
</form>
</aside>
</div>
</x-app-layout>
+231 -181
View File
@@ -2,34 +2,110 @@
@push('styles')
<style>
canvas { max-width: 100% !important; }
.custom-scrollbar::-webkit-scrollbar { width: 4px; }
.custom-scrollbar::-webkit-scrollbar { width: 5px; }
.custom-scrollbar::-webkit-scrollbar-track { background: #f1f5f9; }
.custom-scrollbar::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 10px; }
.animate-modal-enter { animation: modalFadeIn 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
@keyframes modalFadeIn {
from { opacity: 0; transform: scale(0.95) translateY(20px); }
to { opacity: 1; transform: scale(1) translateY(0); }
}
</style>
@endpush
@php
// Mengambil daftar penyakit yang MASIH AKTIF untuk dropdown
$activePerawatans = $cat->treatments->where('status_perawatan', 1);
@endphp
<div class="max-w-[1600px] mx-auto space-y-8 pb-12">
{{-- 1. Header Section --}}
<div class="flex flex-col md:flex-row md:items-center justify-between gap-6">
<div class="flex flex-col md:flex-row md:items-center justify-between gap-6 px-2">
<div class="flex items-center gap-4">
<a href="{{ route('cats.index') }}" class="p-3 bg-white border border-slate-200 rounded-2xl text-slate-400 hover:text-indigo-600 transition-all shadow-sm active:scale-90">
<i class="fas fa-arrow-left"></i>
</a>
<div>
<div class="flex items-center gap-3">
<h2 class="text-3xl font-black text-slate-800 tracking-tight leading-none">{{ $cat->nama_kucing }}</h2>
<h2 class="text-3xl font-black text-slate-800 tracking-tight leading-none uppercase">{{ $cat->nama_kucing }}</h2>
{!! $cat->gender_icon !!}
</div>
<p class="text-sm text-slate-500 font-medium italic uppercase tracking-widest mt-1">Medical Record #FE-{{ str_pad($cat->id, 5, '0', STR_PAD_LEFT) }}</p>
<p class="text-sm text-slate-500 font-medium italic uppercase tracking-widest mt-1">Medis Record #FE-{{ str_pad($cat->id, 5, '0', STR_PAD_LEFT) }}</p>
</div>
</div>
<div class="flex items-center gap-3">
<a href="{{ route('cats.pdf', $cat->id) }}" target="_blank" class="inline-flex items-center px-6 py-3.5 bg-rose-600 text-white text-[10px] font-black rounded-2xl hover:bg-rose-700 transition-all shadow-lg shadow-rose-100 active:scale-95">
<i class="fas fa-file-pdf mr-2 text-sm"></i> CETAK MEDICAL PASS
<div class="flex flex-wrap items-center gap-3">
<a href="{{ route('medical-records.bulk.create') }}" class="inline-flex items-center px-6 py-3.5 bg-indigo-50 text-indigo-600 border border-indigo-100 text-[10px] font-black rounded-2xl hover:bg-indigo-600 hover:text-white transition-all shadow-sm active:scale-95">
<i class="fas fa-layer-group mr-2 text-sm"></i> BULK TREATMENT
</a>
<a href="{{ route('cats.medical-report', $cat->id) }}" class="inline-flex items-center px-6 py-3.5 bg-rose-600 text-white text-[10px] font-black rounded-2xl hover:bg-rose-700 transition-all shadow-lg shadow-rose-100 active:scale-95">
<i class="fas fa-file-medical mr-2 text-sm"></i> UNDUH HEALTH LEDGER
</a>
{{-- PROTEKSI TOMBOL UPDATE: Hanya muncul jika memiliki izin Update ATAU Delete --}}
{{-- ========================================== --}}
{{-- TOMBOL & MODAL HANYA MUNCUL JIKA ADA PENYAKIT AKTIF --}}
{{-- ========================================== --}}
@if($activePerawatans->count() > 0)
<div x-data="{ openModal: false }" class="inline-block">
<button @click="openModal = true" type="button"
class="inline-flex items-center px-6 py-3.5 bg-emerald-600 text-white text-[10px] font-black rounded-2xl hover:bg-emerald-700 transition-all shadow-lg shadow-emerald-100 active:scale-95 animate-pulse">
<i class="fas fa-notes-medical mr-2 text-sm"></i> RESOLVE CLINICAL CASE
</button>
{{-- Modal Backdrop --}}
<div x-show="openModal"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
class="fixed inset-0 z-50 overflow-y-auto bg-slate-900/60 backdrop-blur-sm flex items-center justify-center p-4"
x-cloak>
{{-- Modal Content --}}
<div @click.away="openModal = false" class="bg-white rounded-[2.5rem] border border-slate-100 shadow-2xl max-w-md w-full p-8 transform transition-all space-y-6">
<div class="flex justify-between items-start">
<div>
<h3 class="text-lg font-black text-slate-800 uppercase tracking-tight">Resolusi Penyakit</h3>
<p class="text-[10px] text-slate-400 font-bold uppercase tracking-wider mt-1">Pilih kasus yang sudah sembuh</p>
</div>
<button @click="openModal = false" type="button" class="text-slate-400 hover:text-rose-600 transition-colors">
<i class="fas fa-times-circle text-xl"></i>
</button>
</div>
<form action="{{ route('cats.complete-treatment', $cat->id) }}" method="POST" class="space-y-4">
@csrf
@method('PATCH')
<div class="space-y-2">
<label class="block text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Pilih Keluhan / Penyakit</label>
<select name="treatment_id" required class="w-full bg-slate-50 border-none rounded-2xl text-xs font-bold p-4 text-slate-700 focus:ring-4 focus:ring-indigo-500/20 outline-none">
<option value="" disabled selected>-- Pilih Penyakit yang Sembuh --</option>
@foreach($activePerawatans as $tr)
<option value="{{ $tr->id }}">{{ $tr->keluhan }} (Tanggal: {{ $tr->tanggal->format('d/m/Y') }})</option>
@endforeach
</select>
</div>
<div class="space-y-2">
<label class="block text-[10px] font-black text-slate-400 uppercase tracking-widest ml-1">Kondisi Pasca Sakit / Remark</label>
<textarea name="remark_pasca_sakit" rows="4" required placeholder="Catat perkembangan... (Contoh: Jamur sembuh total)" class="w-full bg-slate-50 border-none rounded-2xl text-xs font-bold p-4 text-slate-700 focus:ring-4 focus:ring-indigo-500/20 outline-none"></textarea>
</div>
<div class="grid grid-cols-2 gap-3 pt-2">
<button @click="openModal = false" type="button" class="w-full bg-slate-100 text-slate-500 py-3.5 rounded-xl text-[10px] font-black uppercase tracking-widest hover:bg-slate-200 transition-all">Batal</button>
<button type="submit" class="w-full bg-emerald-600 text-white py-3.5 rounded-xl text-[10px] font-black uppercase tracking-widest hover:bg-emerald-700 shadow-lg shadow-emerald-100 transition-all">Simpan Resolusi</button>
</div>
</form>
</div>
</div>
</div>
@endif
{{-- ========================================== --}}
@if(Gate::allows('check-access', ['cats', 'update']) || Gate::allows('check-access', ['cats', 'delete']))
<a href="{{ route('cats.edit', $cat->id) }}" class="inline-flex items-center px-6 py-3.5 bg-white border border-slate-200 text-slate-600 text-[10px] font-black rounded-2xl hover:bg-slate-50 transition-all shadow-sm active:scale-95">
<i class="fas fa-edit mr-2 text-indigo-500 text-sm"></i> UPDATE DATA
@@ -38,26 +114,19 @@
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8 px-2">
{{-- Column 1: Profile & Core Identity --}}
<div class="space-y-6">
<div class="bg-white border border-slate-200 rounded-[3rem] p-8 shadow-sm text-center relative overflow-hidden group">
<div class="absolute top-0 left-0 p-6">
{!! $cat->status_badge !!}
</div>
<div class="absolute top-0 left-0 p-6 z-10">{!! $cat->status_badge !!}</div>
<div class="w-48 h-48 mx-auto rounded-[3rem] bg-slate-50 overflow-hidden ring-8 ring-slate-50 shadow-xl mb-6 transition-transform group-hover:scale-105 duration-500">
<img src="{{ $cat->foto_url }}" class="w-full h-full object-cover">
</div>
<h3 class="text-2xl font-black text-slate-800 mb-6 tracking-tighter uppercase">{{ $cat->nama_kucing }}</h3>
<div class="grid grid-cols-2 gap-4 text-left border-t border-slate-100 pt-6">
<div class="bg-slate-50/50 p-4 rounded-2xl border border-slate-100">
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest mb-2">Registry</p>
<div class="flex flex-wrap gap-1">
{!! $cat->registry_badges !!}
</div>
<div class="flex flex-wrap gap-1">{!! $cat->registry_badges !!}</div>
</div>
<div class="bg-slate-50/50 p-4 rounded-2xl border border-slate-100 text-center">
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest mb-1">Umur Saat Ini</p>
@@ -77,25 +146,22 @@
<span class="text-xs font-bold text-slate-400 uppercase">Pedigree No.</span>
<span class="text-xs font-black text-slate-700">{{ $cat->pedigree ?? '-' }}</span>
</div>
<div class="flex justify-between items-center">
<span class="text-xs font-bold text-slate-400 uppercase">Lokasi Kandang</span>
<span class="px-2 py-0.5 bg-indigo-50 text-indigo-600 rounded text-[10px] font-black uppercase tracking-widest">{{ $cat->lokasi_kandang ?? 'Global' }}</span>
<div class="flex justify-between items-center pt-3 border-t border-slate-50 mt-1">
<span class="text-xs font-bold text-slate-400 uppercase">Sertifikat Ped</span>
<div class="flex items-center gap-2">
@if($cat->sertifikat_ped_file)
<span class="text-[9px] font-black text-emerald-600 bg-emerald-50 px-2 py-1 rounded-md uppercase"><i class="fas fa-check-circle mr-1"></i> Tersedia</span>
@else
<span class="text-[9px] font-black text-rose-500 bg-rose-50 px-2 py-1 rounded-md uppercase"><i class="fas fa-times-circle mr-1"></i> Kosong</span>
@endif
<a href="{{ route('cats.pedigree', $cat->id) }}" class="flex items-center justify-center px-4 py-2.5 bg-indigo-50 text-indigo-600 rounded-xl hover:bg-indigo-600 hover:text-white transition-all font-black text-[10px] uppercase tracking-widest shadow-sm">
<i class="fas fa-folder-open mr-2"></i> Buka
</a>
</div>
</div>
<div class="flex justify-between items-center">
<span class="text-xs font-bold text-slate-400 uppercase">PIC Bertugas</span>
<span class="text-xs font-black text-slate-700">{{ $cat->pic?->name ?? 'System' }}</span>
</div>
</div>
@php $isOverdue = $cat->updated_at->diffInDays(now()) >= 3; @endphp
<div class="mt-6 p-5 {{ $isOverdue ? 'bg-rose-50 border-rose-100' : 'bg-emerald-50 border-emerald-100' }} border rounded-3xl">
<div class="flex justify-between items-center mb-1">
<span class="text-[9px] font-black uppercase {{ $isOverdue ? 'text-rose-600' : 'text-emerald-600' }}">Monitoring Berat</span>
<span class="text-[9px] font-bold text-slate-400 uppercase italic">{{ $cat->updated_at->diffForHumans() }}</span>
</div>
<div class="flex items-baseline gap-1">
<span class="text-2xl font-black text-slate-800">{{ number_format($cat->berat_badan, 2) }}</span>
<span class="text-xs font-black text-slate-400 uppercase">Kg</span>
<span class="text-xs font-black text-slate-700">{{ $cat->pic?->name ?? 'Sistem' }}</span>
</div>
</div>
</div>
@@ -104,33 +170,29 @@
{{-- Column 2: Lineage & Health Routine --}}
<div class="space-y-8">
<div class="bg-white border border-slate-200 rounded-[3rem] p-8 shadow-sm">
<h4 class="text-xs font-black text-slate-800 uppercase tracking-widest border-b border-slate-100 pb-4 mb-6">Parental Intelligence</h4>
<h4 class="text-xs font-black text-slate-800 uppercase tracking-widest border-b border-slate-100 pb-4 mb-6">Data Induk</h4>
<div class="space-y-4">
{{-- SIRE --}}
<div class="p-4 bg-indigo-50/30 border border-indigo-100 rounded-3xl flex items-center gap-4 hover:bg-indigo-50 transition-colors cursor-default">
<div class="w-12 h-12 bg-white border border-indigo-100 text-indigo-600 rounded-2xl flex items-center justify-center shadow-sm">
<i class="fas fa-mars text-lg"></i>
</div>
<div @if($cat->sire_id) onclick="window.location.href='{{ route('cats.show', $cat->sire_id) }}'" @endif
class="p-4 bg-indigo-50/30 border border-indigo-100 rounded-3xl flex items-center gap-4 hover:bg-indigo-50 transition-colors {{ $cat->sire_id ? 'cursor-pointer' : 'cursor-default' }}">
<div class="w-12 h-12 bg-white border border-indigo-100 text-indigo-600 rounded-2xl flex items-center justify-center shadow-sm"><i class="fas fa-mars text-lg"></i></div>
<div class="flex-1">
<p class="text-[9px] font-black text-indigo-400 uppercase tracking-widest">Sire (Pejantan)</p>
<p class="text-sm font-black text-slate-700 uppercase leading-none mt-1">{{ $cat->sire->nama_kucing }}</p>
<p class="text-sm font-black text-slate-700 uppercase leading-none mt-1">{{ $cat->sire->nama_kucing ?? 'Unknown' }}</p>
</div>
</div>
{{-- DAM --}}
<div class="p-4 bg-rose-50/30 border border-rose-100 rounded-3xl flex items-center gap-4 hover:bg-rose-50 transition-colors cursor-default">
<div class="w-12 h-12 bg-white border border-rose-100 text-rose-600 rounded-2xl flex items-center justify-center shadow-sm">
<i class="fas fa-venus text-lg"></i>
</div>
<div @if($cat->dam_id) onclick="window.location.href='{{ route('cats.show', $cat->dam_id) }}'" @endif
class="p-4 bg-rose-50/30 border border-rose-100 rounded-3xl flex items-center gap-4 hover:bg-rose-50 transition-colors {{ $cat->dam_id ? 'cursor-pointer' : 'cursor-default' }}">
<div class="w-12 h-12 bg-white border border-rose-100 text-rose-600 rounded-2xl flex items-center justify-center shadow-sm"><i class="fas fa-venus text-lg"></i></div>
<div class="flex-1">
<p class="text-[9px] font-black text-rose-400 uppercase tracking-widest">Dam (Betina)</p>
<p class="text-sm font-black text-slate-700 uppercase leading-none mt-1">{{ $cat->dam->nama_kucing }}</p>
<p class="text-sm font-black text-slate-700 uppercase leading-none mt-1">{{ $cat->dam->nama_kucing ?? 'Unknown' }}</p>
</div>
</div>
</div>
</div>
<div class="bg-slate-900 rounded-[3rem] p-8 text-white shadow-2xl relative overflow-hidden">
<h4 class="text-xs font-black uppercase tracking-widest border-b border-white/10 pb-4 mb-6 italic">Routine Medical Calendar</h4>
<h4 class="text-xs font-black uppercase tracking-widest border-b border-white/10 pb-4 mb-6 italic">Current Health Reminders</h4>
<div class="grid grid-cols-1 gap-4 relative z-10">
@foreach([
['icon' => 'fa-syringe', 'label' => 'Vaksin', 'field' => 'jadwal_vaksin'],
@@ -161,121 +223,143 @@
<h4 class="font-black text-slate-800 uppercase tracking-tighter text-lg leading-none">Analisis Berat</h4>
<p class="text-[10px] text-slate-400 font-black uppercase mt-1">Growth Index (Kg)</p>
</div>
<div class="w-12 h-12 bg-emerald-50 text-emerald-500 rounded-2xl flex items-center justify-center">
<i class="fas fa-chart-line text-lg"></i>
</div>
</div>
<div class="relative h-[250px]">
<canvas id="weightChart"></canvas>
<div class="w-12 h-12 bg-emerald-50 text-emerald-500 rounded-2xl flex items-center justify-center"><i class="fas fa-chart-line text-lg"></i></div>
</div>
<div class="relative h-[250px]"><canvas id="weightChart"></canvas></div>
</div>
{{-- PROTEKSI QUICK ACTION: Hanya jika bisa Create Treatment --}}
@can('check-access', ['treatments', 'create'])
<div class="bg-indigo-600 rounded-[3rem] p-8 text-white shadow-xl shadow-indigo-100 flex flex-col justify-between h-[250px] group overflow-hidden relative">
@can('check-access', ['cats', 'update'])
<div class="bg-indigo-600 rounded-[3rem] p-8 text-white shadow-xl shadow-indigo-100 flex flex-col justify-between h-[300px] group overflow-hidden relative">
<div class="relative z-10">
<h4 class="text-xs font-black uppercase tracking-widest mb-2 border-b border-white/20 pb-3">Quick Action</h4>
<p class="text-[10px] text-indigo-100/60 leading-relaxed italic uppercase font-bold tracking-tighter">Gunakan menu ini untuk mencatat tindakan medis segera.</p>
<h4 class="text-xs font-black uppercase tracking-widest mb-2 border-b border-white/20 pb-3">Tindakan medis</h4>
<p class="text-[10px] text-indigo-100/60 leading-relaxed italic uppercase font-bold tracking-tighter">Log tindakan kesehatan cepat atau pengobatan klinis.</p>
</div>
<div class="flex flex-col gap-3 relative z-10">
<a href="{{ route('medical-records.create', $cat->id) }}" class="w-full flex items-center justify-center gap-3 p-4 bg-white text-indigo-600 rounded-2xl font-black uppercase text-[10px] shadow-lg hover:bg-indigo-50 transition-all active:scale-95">
<i class="fas fa-calendar-check"></i> LOG ROUTINE LEDGER
</a>
<a href="{{ route('treatments.create', ['cat_id' => $cat->id]) }}" class="w-full flex items-center justify-center gap-3 p-4 bg-indigo-500 text-white border border-indigo-400 rounded-2xl font-black uppercase text-[10px] shadow-lg hover:bg-indigo-400 transition-all active:scale-95">
<i class="fas fa-briefcase-medical"></i> LOG CLINICAL CASE
</a>
</div>
<a href="{{ route('treatments.create', ['cat_id' => $cat->id]) }}" class="relative z-10 flex items-center justify-center gap-3 p-5 bg-white text-indigo-600 rounded-3xl font-black uppercase text-xs shadow-xl hover:scale-105 transition-all active:scale-95">
<i class="fas fa-file-medical-alt text-lg"></i> Tambah Rekam Medis
</a>
<i class="fas fa-heartbeat absolute -bottom-10 -left-10 text-[10rem] text-white/5"></i>
</div>
@endcan
</div>
</div>
{{-- Log Section: Medical History Timeline --}}
<div class="bg-white border border-slate-200 rounded-[3rem] overflow-hidden shadow-sm">
{{-- Comprehensive Health History --}}
<div class="bg-white border border-slate-200 rounded-[3.5rem] overflow-hidden shadow-sm mx-2">
<div class="p-10 border-b border-slate-100 bg-slate-50/50 flex flex-col md:flex-row justify-between items-center gap-4">
<div class="flex items-center gap-4">
<div class="w-12 h-12 bg-indigo-600 text-white rounded-2xl flex items-center justify-center shadow-lg shadow-indigo-100">
<i class="fas fa-book-medical text-xl"></i>
</div>
<div>
<h4 class="font-black text-slate-800 uppercase tracking-tighter text-xl leading-none">Comprehensive Health History</h4>
<p class="text-[10px] text-slate-400 font-bold uppercase tracking-[0.2em] mt-2">Jejak medis dari pertama hingga rencana mendatang</p>
</div>
</div>
<span class="text-[10px] font-black text-indigo-600 bg-white border border-indigo-100 px-6 py-2.5 rounded-full shadow-sm">
{{ $cat->medicalRecords->count() }} TOTAL RECORDS
</span>
</div>
<div class="p-10 max-h-[800px] overflow-y-auto custom-scrollbar bg-white">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
@forelse($cat->medicalRecords->sortByDesc('date_given') as $record)
<div class="p-8 rounded-[2.5rem] border border-slate-100 bg-slate-50/30 hover:bg-white hover:border-indigo-100 hover:shadow-xl transition-all duration-500 group/item relative overflow-hidden">
<i class="fas {{ $record->type === 'Vaccine' ? 'fa-syringe' : ($record->type === 'Grooming' ? 'fa-bath' : 'fa-pills') }} absolute -bottom-4 -right-4 text-7xl text-slate-100/50 group-hover/item:text-indigo-500/10 transition-colors"></i>
<div class="flex items-start justify-between mb-6 relative z-10">
<div class="w-12 h-12 rounded-2xl flex items-center justify-center shadow-sm
{{ $record->type === 'Vaccine' ? 'bg-blue-600 text-white' :
($record->type === 'Deworming' ? 'bg-emerald-500 text-white' :
($record->type === 'Flea Perawatan' ? 'bg-amber-500 text-white' : 'bg-pink-500 text-white')) }}">
<i class="fas {{ $record->type === 'Vaccine' ? 'fa-syringe' : ($record->type === 'Grooming' ? 'fa-bath' : 'fa-pills') }} text-sm"></i>
</div>
<span class="text-[10px] font-black text-slate-800 uppercase tracking-widest">{{ $record->date_given->format('d M Y') }}</span>
</div>
<div class="relative z-10">
<h5 class="text-base font-black text-slate-800 uppercase tracking-tight mb-1">{{ $record->treatment_name }}</h5>
<div class="flex items-center gap-2 mb-4">
<span class="text-[8px] font-black text-indigo-600 bg-indigo-50 px-2.5 py-1 rounded-lg border border-indigo-100 uppercase italic">{{ $record->type }}</span>
@if($record->dosage && $record->type !== 'Grooming')
<span class="text-[8px] font-black text-emerald-600 bg-emerald-50 px-2.5 py-1 rounded-lg border border-emerald-100 uppercase tracking-widest">
DOSIS: {{ $record->dosage }} {{ $record->unit }}
</span>
@endif
</div>
<p class="text-[11px] text-slate-500 font-medium italic mb-6 leading-relaxed bg-white/50 p-3 rounded-xl border border-dashed border-slate-200">
"{{ $record->notes ?? 'Pemberian rutin tanpa keluhan klinis.' }}"
</p>
</div>
</div>
@empty
<div class="col-span-full py-20 text-center text-slate-400 font-black uppercase text-xs">No Records Found</div>
@endforelse
</div>
</div>
</div>
{{-- Klinis Case History --}}
<div class="bg-white border border-slate-200 rounded-[3rem] overflow-hidden shadow-sm mx-2">
<div class="p-8 border-b border-slate-100 bg-slate-50/50 flex justify-between items-center">
<div class="flex items-center gap-3">
<i class="fas fa-history text-slate-400"></i>
<h4 class="font-black text-slate-800 uppercase tracking-tighter text-lg">Historical Medical Log</h4>
<h4 class="font-black text-slate-800 uppercase tracking-tighter text-lg">Klinis Case History (Non-Routine)</h4>
</div>
<span class="text-[10px] font-black text-indigo-600 bg-white border border-indigo-100 px-5 py-2 rounded-full shadow-sm">{{ $cat->treatments->count() }} REKAMAN</span>
</div>
<div class="p-10 max-h-[800px] overflow-y-auto custom-scrollbar">
<div class="p-10 max-h-[600px] overflow-y-auto custom-scrollbar">
<div class="relative space-y-12">
<div class="absolute left-[11px] top-2 bottom-2 w-0.5 bg-slate-100"></div>
@forelse($cat->treatments->sortByDesc('tanggal') as $treatment)
<div class="relative flex items-start gap-8 group">
<div class="z-10 w-6 h-6 rounded-full bg-white border-4 border-indigo-500 ring-8 ring-indigo-50 shadow-md"></div>
{{-- Dot Timeline dinamis sesuai status_perawatan --}}
<div class="z-10 w-6 h-6 rounded-full border-4 ring-8 shadow-md
{{ $treatment->status_perawatan == 2 ? 'bg-emerald-500 border-white ring-emerald-50' : 'bg-white border-rose-500 ring-rose-50' }}">
</div>
<div class="flex-1 space-y-4">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<p class="text-xs font-black text-indigo-600 uppercase tracking-widest bg-indigo-50 px-3 py-1 rounded-lg border border-indigo-100">
{{ $treatment->tanggal->format('d F Y') }}
</p>
<span class="text-[10px] text-slate-400 font-bold italic">{{ $treatment->tanggal->diffForHumans() }}</span>
</div>
<p class="text-xs font-black text-indigo-600 uppercase tracking-widest bg-indigo-50 px-3 py-1 rounded-lg border border-indigo-100">{{ $treatment->tanggal->format('d F Y') }}</p>
{{-- PROTEKSI EDIT LOG: Hanya jika bisa Update Treatment --}}
@can('check-access', ['treatments', 'update'])
<a href="{{ route('treatments.edit', $treatment->id) }}" class="opacity-0 group-hover:opacity-100 p-2.5 bg-slate-50 text-slate-400 hover:text-amber-600 hover:bg-amber-50 rounded-xl transition-all" title="Edit Log">
<i class="fas fa-pen text-xs"></i>
</a>
@endcan
{{-- LABEL STATUS PADA KARTU HISTORY --}}
@if($treatment->status_perawatan == 2)
<span class="text-[9px] font-black text-emerald-600 bg-emerald-50 px-3 py-1 rounded-full uppercase tracking-widest border border-emerald-100"><i class="fas fa-check-circle mr-1"></i> SEMBUH</span>
@else
<span class="text-[9px] font-black text-rose-600 bg-rose-50 px-3 py-1 rounded-full uppercase tracking-widest border border-rose-100 animate-pulse"><i class="fas fa-procedures mr-1"></i> AKTIF</span>
@endif
</div>
<div class="bg-white rounded-[2.5rem] p-8 border border-slate-100 shadow-sm group-hover:border-indigo-200 transition-all duration-300">
<div class="bg-white rounded-[2.5rem] p-8 border {{ $treatment->status_perawatan == 2 ? 'border-emerald-100' : 'border-rose-100' }} shadow-sm transition-all duration-300">
<div class="flex flex-col md:flex-row gap-10">
<div class="flex-1">
<h5 class="text-lg font-black text-slate-800 mb-2 uppercase tracking-tight">{{ $treatment->keluhan }}</h5>
<p class="text-sm text-slate-500 font-medium leading-relaxed italic border-l-4 border-indigo-100 pl-4 mb-6">Diagnosa: {{ $treatment->diagnosa }}</p>
<p class="text-sm text-slate-500 font-medium leading-relaxed italic border-l-4 {{ $treatment->status_perawatan == 2 ? 'border-emerald-200' : 'border-rose-200' }} pl-4 mb-6">Diagnosa: {{ $treatment->diagnosa }}</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="flex items-center gap-4 p-4 bg-slate-50/50 rounded-2xl">
<div class="w-10 h-10 rounded-xl bg-rose-50 flex items-center justify-center text-rose-500">
<i class="fas fa-capsules"></i>
</div>
<div>
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Therapy</p>
<p class="text-xs font-black text-slate-800 uppercase">{{ $treatment->nama_obat }} ({{ $treatment->dosis }})</p>
</div>
</div>
<div class="flex items-center gap-4 p-4 bg-slate-50/50 rounded-2xl">
<div class="w-10 h-10 rounded-xl bg-indigo-50 flex items-center justify-center text-indigo-500">
<i class="fas fa-user-md"></i>
</div>
<div>
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Medical Staff</p>
<p class="text-xs font-black text-slate-800 uppercase">{{ $treatment->user?->name ?? 'System' }}</p>
</div>
</div>
<div class="flex items-center gap-4 p-4 bg-slate-50/50 rounded-2xl mb-4">
<div class="w-10 h-10 rounded-xl bg-indigo-50 flex items-center justify-center text-indigo-500"><i class="fas fa-capsules"></i></div>
<div><p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Therapy</p><p class="text-xs font-black text-slate-800 uppercase">{{ $treatment->nama_obat }} ({{ $treatment->dosis }})</p></div>
</div>
</div>
@if($treatment->foto_bukti)
<div class="shrink-0">
<div class="w-44 h-44 rounded-[2.5rem] overflow-hidden ring-4 ring-slate-100 shadow-lg group/img relative">
<img src="{{ asset('storage/' . $treatment->foto_bukti) }}" class="w-full h-full object-cover">
<div class="absolute inset-0 bg-indigo-600/20 opacity-0 group-hover/img:opacity-100 transition-opacity flex items-center justify-center cursor-zoom-in">
<i class="fas fa-search-plus text-white text-2xl"></i>
{{-- TAMPILKAN REMARK JIKA SUDAH SEMBUH --}}
@if($treatment->status_perawatan == 2 && $treatment->remark_pasca_sakit)
<div class="bg-emerald-50/50 p-4 rounded-2xl border border-emerald-100/50 mt-4">
<p class="text-[9px] font-black text-emerald-600 uppercase tracking-widest mb-1"><i class="fas fa-clipboard-check mr-1"></i> Catatan Resolusi Sembuh</p>
<p class="text-xs font-bold text-slate-600 italic">"{{ $treatment->remark_pasca_sakit }}"</p>
</div>
</div>
@endif
</div>
@if($treatment->foto_bukti)
<div class="shrink-0"><div class="w-44 h-44 rounded-[2.5rem] overflow-hidden ring-4 ring-slate-100 shadow-lg"><img src="{{ asset('storage/' . $treatment->foto_bukti) }}" class="w-full h-full object-cover"></div></div>
@endif
</div>
@if($treatment->keterangan)
<div class="mt-8 p-5 bg-indigo-50/30 rounded-2xl border-l-4 border-indigo-200">
<p class="text-[11px] text-slate-600 font-bold italic">
<i class="fas fa-quote-left mr-3 text-indigo-200"></i> {{ $treatment->keterangan }}
</p>
</div>
@endif
</div>
</div>
</div>
@empty
<div class="text-center py-32 bg-slate-50/30 rounded-[4rem] border-4 border-dashed border-slate-100">
<i class="fas fa-notes-medical text-slate-200 text-5xl mb-4"></i>
<p class="text-slate-400 font-black uppercase text-xs tracking-[0.3em]">No Historical Medical Logs Recorded</p>
</div>
<div class="text-center py-10 text-slate-300 uppercase font-black text-xs">No Klinis Cases</div>
@endforelse
</div>
</div>
@@ -287,65 +371,31 @@
<script>
document.addEventListener('DOMContentLoaded', function() {
const ctx = document.getElementById('weightChart');
{{-- Data diurutkan dari yang terlama ke terbaru untuk Chart --}}
const weightHistories = {!! json_encode($cat->weightHistories->sortBy('created_at')->values() ?? []) !!};
if(!weightHistories || weightHistories.length === 0) {
ctx.parentNode.innerHTML = '<div class="h-full flex flex-col items-center justify-center text-slate-300 italic text-xs gap-3"><i class="fas fa-weight-hanging text-4xl opacity-20"></i>No growth data available yet.</div>';
return;
if(ctx && weightHistories && weightHistories.length > 0) {
const labels = weightHistories.map(d => new Date(d.created_at).toLocaleDateString('id-ID', { day: '2-digit', month: 'short' }));
const data = weightHistories.map(d => d.berat);
new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Berat (Kg)',
data: data,
borderColor: '#10b981',
backgroundColor: 'rgba(16, 185, 129, 0.1)',
borderWidth: 5,
tension: 0.4,
fill: true,
pointBackgroundColor: '#fff',
pointBorderColor: '#10b981',
pointBorderWidth: 3,
pointRadius: 4
}]
},
options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } }, scales: { y: { beginAtZero: false }, x: { grid: { display: false } } } }
});
}
const labels = weightHistories.map(d => {
const date = new Date(d.created_at);
return date.toLocaleDateString('id-ID', { day: '2-digit', month: 'short' });
});
const data = weightHistories.map(d => d.berat);
new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Weight (Kg)',
data: data,
borderColor: '#10b981',
backgroundColor: (context) => {
const chart = context.chart;
const {ctx, chartArea} = chart;
if (!chartArea) return null;
const gradient = ctx.createLinearGradient(0, chartArea.bottom, 0, chartArea.top);
gradient.addColorStop(0, 'rgba(16, 185, 129, 0)');
gradient.addColorStop(1, 'rgba(16, 185, 129, 0.1)');
return gradient;
},
borderWidth: 5,
tension: 0.4,
fill: true,
pointBackgroundColor: '#fff',
pointBorderColor: '#10b981',
pointBorderWidth: 3,
pointRadius: 4,
pointHoverRadius: 8
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: { legend: { display: false } },
scales: {
y: {
beginAtZero: false,
grid: { borderDash: [5, 5], color: '#f1f5f9' },
ticks: { font: { size: 10, weight: 'bold' }, color: '#94a3b8' }
},
x: {
grid: { display: false },
ticks: { font: { size: 10, weight: 'bold' }, color: '#94a3b8' }
}
}
}
});
});
</script>
@endpush