352 lines
23 KiB
PHP
352 lines
23 KiB
PHP
<x-app-layout>
|
|
@push('styles')
|
|
<style>
|
|
canvas { max-width: 100% !important; }
|
|
.custom-scrollbar::-webkit-scrollbar { width: 4px; }
|
|
.custom-scrollbar::-webkit-scrollbar-track { background: #f1f5f9; }
|
|
.custom-scrollbar::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 10px; }
|
|
</style>
|
|
@endpush
|
|
|
|
<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 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>
|
|
{!! $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>
|
|
</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
|
|
</a>
|
|
|
|
{{-- PROTEKSI TOMBOL UPDATE: Hanya muncul jika memiliki izin Update ATAU Delete --}}
|
|
@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
|
|
</a>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
{{-- 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="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>
|
|
<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>
|
|
<p class="text-xs font-black text-slate-700 tracking-tighter">{{ $cat->age }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white border border-slate-200 rounded-[3rem] p-8 shadow-sm space-y-5">
|
|
<h4 class="text-[10px] font-black text-slate-400 uppercase tracking-widest border-b border-slate-50 pb-3">Informasi Teknis</h4>
|
|
<div class="space-y-4">
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-xs font-bold text-slate-400 uppercase">Microchip</span>
|
|
<span class="text-xs font-black text-slate-700 font-mono">{{ $cat->microchip ?? 'Unchipped' }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<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>
|
|
<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>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- 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>
|
|
<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 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>
|
|
</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 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>
|
|
</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>
|
|
<div class="grid grid-cols-1 gap-4 relative z-10">
|
|
@foreach([
|
|
['icon' => 'fa-syringe', 'label' => 'Vaksin', 'field' => 'jadwal_vaksin'],
|
|
['icon' => 'fa-bug', 'label' => 'Obat Cacing', 'field' => 'jadwal_obat_cacing'],
|
|
['icon' => 'fa-shield-virus', 'label' => 'Obat Kutu', 'field' => 'jadwal_obat_kutu'],
|
|
['icon' => 'fa-bath', 'label' => 'Grooming', 'field' => 'jadwal_grooming']
|
|
] as $item)
|
|
<div class="flex items-center justify-between p-4 bg-white/5 rounded-2xl border border-white/5 hover:bg-white/10 transition-all">
|
|
<div class="flex items-center gap-3">
|
|
<i class="fas {{ $item['icon'] }} text-xs text-slate-400"></i>
|
|
<span class="text-[10px] font-black uppercase tracking-widest text-slate-300">{{ $item['label'] }}</span>
|
|
</div>
|
|
<span class="text-[11px] font-black {{ $cat->{$item['field']} && $cat->{$item['field']}->isPast() ? 'text-rose-400' : 'text-white' }}">
|
|
{{ $cat->{$item['field']} ? $cat->{$item['field']}->format('d M Y') : 'NOT SET' }}
|
|
</span>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
<i class="fas fa-paw absolute -bottom-10 -right-10 text-[12rem] text-white/5 -rotate-12"></i>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Column 3: Growth Analytics & Actions --}}
|
|
<div class="space-y-8">
|
|
<div class="bg-white border border-slate-200 rounded-[3rem] p-8 shadow-sm">
|
|
<div class="flex items-center justify-between mb-8">
|
|
<div>
|
|
<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>
|
|
</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">
|
|
<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>
|
|
</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">
|
|
<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>
|
|
</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="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>
|
|
|
|
<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>
|
|
|
|
{{-- 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
|
|
</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="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>
|
|
|
|
<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>
|
|
</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>
|
|
</div>
|
|
</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>
|
|
@endforelse
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@push('scripts')
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
<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;
|
|
}
|
|
|
|
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
|
|
</x-app-layout> |