diff --git a/app/Http/Controllers/DiagnosisController.php b/app/Http/Controllers/DiagnosisController.php
index 04c60e7..1ab3b32 100644
--- a/app/Http/Controllers/DiagnosisController.php
+++ b/app/Http/Controllers/DiagnosisController.php
@@ -76,10 +76,12 @@ public function prosesDiagnosis(Request $request)
]);
}
-return redirect()->route('hasil-diagnosis')
-->with('diagnosis', $diagnosis)
-->with('gejala', $inputNama);
-$biodataId = session('biodata_id');
+session([
+ 'diagnosis' => $diagnosis,
+ 'gejala' => $inputNama,
+]);
+
+return redirect()->route('hasil-diagnosis');
}
// 🔥 halaman hasil
@@ -137,6 +139,7 @@ public function simpanBiodata(Request $request)
'umur_kucing' => 'required|numeric',
'jenis_kelamin' => 'required',
'berat_badan' => 'required|numeric',
+ 'alamat' => 'required|in:Ajung,Ambulu,Arjasa,Balung,Bangsalsari,Gumukmas,Jelbuk,Jenggawah,Jombang,Kalisat,Kaliwates,Kencong,Ledokombo,Mayang,Mumbulsari,Pakusari,Panti,Patrang,Puger,Rambipuji,Semboro,Silo,Sukorambi,Sukowono,Sumberbaru,Sumberjambe,Sumbersari,Tanggul,Tempurejo,Umbulsari,Wuluhan',
]);
$data = \App\Models\Biodata::create([
@@ -179,4 +182,4 @@ private function getDiseaseDescription(string $diseaseName): string
return '';
}
-}
\ No newline at end of file
+}
diff --git a/app/Http/Controllers/LandingController.php b/app/Http/Controllers/LandingController.php
new file mode 100644
index 0000000..474c926
--- /dev/null
+++ b/app/Http/Controllers/LandingController.php
@@ -0,0 +1,239 @@
+latest()->take(3)->get()
+ : collect();
+ $range = $request->query('range') === 'week' ? 'week' : 'month';
+
+ return view('landing', [
+ 'ulasan' => $ulasan,
+ 'diseaseNews' => $this->buildDiseaseNews($range),
+ ]);
+ }
+
+ private function buildDiseaseNews(string $range): array
+ {
+ $startDate = $range === 'week'
+ ? Carbon::now()->subDays(6)->startOfDay()
+ : Carbon::now()->subDays(29)->startOfDay();
+
+ $periodLabel = $range === 'week' ? '7 hari terakhir' : '30 hari terakhir';
+
+ if (!Schema::hasTable('biodata')) {
+ return $this->emptyDiseaseNews($range, $periodLabel, $startDate);
+ }
+
+ $diseaseStats = Biodata::query()
+ ->select('hasil_diagnosis', DB::raw('COUNT(*) as total'))
+ ->whereNotNull('hasil_diagnosis')
+ ->where('hasil_diagnosis', '!=', '')
+ ->where('created_at', '>=', $startDate)
+ ->groupBy('hasil_diagnosis')
+ ->orderByDesc('total')
+ ->limit(3)
+ ->get();
+
+ $topDisease = trim((string) ($diseaseStats->first()->hasil_diagnosis ?? ''));
+
+ $areaStats = collect();
+ $areaStatsByDisease = [];
+ if ($topDisease !== '') {
+ $areaStats = Biodata::query()
+ ->where('hasil_diagnosis', $topDisease)
+ ->where('created_at', '>=', $startDate)
+ ->get(['alamat'])
+ ->map(fn ($item) => $this->extractArea((string) ($item->alamat ?? '')))
+ ->filter()
+ ->countBy()
+ ->sortDesc()
+ ->take(6);
+ }
+
+ foreach ($diseaseStats as $row) {
+ $disease = trim((string) $row->hasil_diagnosis);
+ if ($disease === '') {
+ continue;
+ }
+
+ $areas = Biodata::query()
+ ->where('hasil_diagnosis', $disease)
+ ->where('created_at', '>=', $startDate)
+ ->get(['alamat'])
+ ->map(fn ($item) => $this->extractArea((string) ($item->alamat ?? '')))
+ ->filter()
+ ->countBy()
+ ->sortDesc()
+ ->take(6);
+
+ $areaStatsByDisease[$disease] = [
+ 'labels' => $areas->keys()->values(),
+ 'data' => $areas->values()->map(fn ($n) => (int) $n)->values(),
+ ];
+ }
+
+ $knowledge = $this->getDiseaseKnowledge($topDisease);
+
+ return [
+ 'range' => $range,
+ 'period_label' => $periodLabel,
+ 'start_label' => $this->formatDateLabel($startDate),
+ 'end_label' => $this->formatDateLabel(Carbon::now()),
+ 'top_disease' => $topDisease,
+ 'total_cases' => (int) ($diseaseStats->first()->total ?? 0),
+ 'disease_labels' => $diseaseStats->pluck('hasil_diagnosis')->map(fn ($name) => trim((string) $name))->values(),
+ 'disease_data' => $diseaseStats->pluck('total')->map(fn ($n) => (int) $n)->values(),
+ 'area_labels' => $areaStats->keys()->values(),
+ 'area_data' => $areaStats->values()->map(fn ($n) => (int) $n)->values(),
+ 'area_by_disease' => $areaStatsByDisease,
+ 'handling' => $knowledge['pertolongan'] ?? [],
+ 'prevention' => $knowledge['pencegahan'] ?? [],
+ ];
+ }
+
+ private function emptyDiseaseNews(string $range, string $periodLabel, Carbon $startDate): array
+ {
+ return [
+ 'range' => $range,
+ 'period_label' => $periodLabel,
+ 'start_label' => $this->formatDateLabel($startDate),
+ 'end_label' => $this->formatDateLabel(Carbon::now()),
+ 'top_disease' => '',
+ 'total_cases' => 0,
+ 'disease_labels' => collect(),
+ 'disease_data' => collect(),
+ 'area_labels' => collect(),
+ 'area_data' => collect(),
+ 'area_by_disease' => [],
+ 'handling' => [],
+ 'prevention' => [],
+ ];
+ }
+
+ private function extractArea(string $address): string
+ {
+ $address = trim($address);
+ if ($address === '') {
+ return 'Tidak diketahui';
+ }
+
+ $parts = array_values(array_filter(array_map('trim', preg_split('/[,;-]+/', $address))));
+ $selected = $parts[0] ?? $address;
+
+ foreach ($parts as $part) {
+ if (preg_match('/\b(kota|kabupaten|kec\.?|kecamatan|kel\.?|kelurahan|desa)\b/i', $part)) {
+ $selected = $part;
+ break;
+ }
+ }
+
+ $selected = preg_replace('/\s+/', ' ', $selected);
+
+ return mb_convert_case($selected, MB_CASE_TITLE, 'UTF-8');
+ }
+
+ private function formatDateLabel(Carbon $date): string
+ {
+ $months = [
+ 1 => 'Jan', 2 => 'Feb', 3 => 'Mar', 4 => 'Apr', 5 => 'Mei', 6 => 'Jun',
+ 7 => 'Jul', 8 => 'Agu', 9 => 'Sep', 10 => 'Okt', 11 => 'Nov', 12 => 'Des',
+ ];
+
+ return $date->format('d') . ' ' . $months[(int) $date->format('n')] . ' ' . $date->format('Y');
+ }
+
+ private function getDiseaseKnowledge(string $diseaseName): array
+ {
+ if ($diseaseName === '') {
+ return ['pertolongan' => [], 'pencegahan' => []];
+ }
+
+ $rows = $this->readXlsxRows(public_path('data/Bissmilah lagi.xlsx'));
+ foreach ($rows as $row) {
+ $name = trim((string) ($row['Penyakit'] ?? ''));
+ if (mb_strtolower($name) !== mb_strtolower($diseaseName)) {
+ continue;
+ }
+
+ return [
+ 'pertolongan' => $this->splitRecommendation((string) ($row['Pertolongan'] ?? '')),
+ 'pencegahan' => $this->splitRecommendation((string) ($row['Pencegahan'] ?? '')),
+ ];
+ }
+
+ return ['pertolongan' => [], 'pencegahan' => []];
+ }
+
+ private function splitRecommendation(string $value): array
+ {
+ return array_values(array_filter(array_map('trim', explode(';', $value))));
+ }
+
+ private function readXlsxRows(string $path): array
+ {
+ if (!is_file($path) || !class_exists(ZipArchive::class)) {
+ return [];
+ }
+
+ $zip = new ZipArchive();
+ if ($zip->open($path) !== true) {
+ return [];
+ }
+
+ $sharedStrings = [];
+ $sharedXml = $zip->getFromName('xl/sharedStrings.xml');
+ if ($sharedXml !== false) {
+ $shared = simplexml_load_string($sharedXml);
+ foreach ($shared->si ?? [] as $item) {
+ $sharedStrings[] = trim((string) ($item->t ?? ''));
+ }
+ }
+
+ $sheetXml = $zip->getFromName('xl/worksheets/sheet1.xml');
+ $zip->close();
+
+ if ($sheetXml === false) {
+ return [];
+ }
+
+ $sheet = simplexml_load_string($sheetXml);
+ $rows = [];
+ foreach ($sheet->sheetData->row ?? [] as $xmlRow) {
+ $cells = [];
+ foreach ($xmlRow->c as $cell) {
+ $ref = (string) $cell['r'];
+ $column = preg_replace('/\d+/', '', $ref);
+ $value = (string) ($cell->v ?? '');
+ if ((string) $cell['t'] === 's') {
+ $value = $sharedStrings[(int) $value] ?? '';
+ }
+ $cells[$column] = trim($value);
+ }
+ $rows[] = $cells;
+ }
+
+ $headers = array_shift($rows) ?? [];
+ return array_values(array_filter(array_map(function ($row) use ($headers) {
+ $mapped = [];
+ foreach ($headers as $column => $header) {
+ if ($header !== '') {
+ $mapped[$header] = $row[$column] ?? '';
+ }
+ }
+ return $mapped;
+ }, $rows)));
+ }
+}
diff --git a/database/seeders/BiodataTrendSeeder.php b/database/seeders/BiodataTrendSeeder.php
new file mode 100644
index 0000000..0f493f4
--- /dev/null
+++ b/database/seeders/BiodataTrendSeeder.php
@@ -0,0 +1,139 @@
+where('no_telepon', 'like', '08DUMMY%')
+ ->delete();
+
+ $diseases = [
+ [
+ 'name' => 'Scabies',
+ 'category' => 'Parasit',
+ 'symptoms' => ['Gatal hebat', 'Kerak pada telinga', 'Bulu rontok', 'Kulit kemerahan'],
+ 'weight' => 5,
+ ],
+ [
+ 'name' => 'Feline calicivirus',
+ 'category' => 'Virus',
+ 'symptoms' => ['Bersin', 'Sariawan', 'Air liur berlebih', 'Nafsu makan menurun'],
+ 'weight' => 4,
+ ],
+ [
+ 'name' => 'Jamur/Ringworm',
+ 'category' => 'Parasit',
+ 'symptoms' => ['Bulu rontok melingkar', 'Kulit bersisik', 'Gatal', 'Kerak pada kulit'],
+ 'weight' => 4,
+ ],
+ [
+ 'name' => 'Cacingan',
+ 'category' => 'Parasit',
+ 'symptoms' => ['Perut membesar', 'Berat badan turun', 'Muntah', 'Diare'],
+ 'weight' => 3,
+ ],
+ [
+ 'name' => 'FLUTD (Feline Lower Urinary Tract Diseases)',
+ 'category' => 'Virus / Lingkungan',
+ 'symptoms' => ['Sulit buang air kecil', 'Sering ke litter box', 'Urin berdarah', 'Nyeri saat pipis'],
+ 'weight' => 3,
+ ],
+ [
+ 'name' => 'Diare Non Spesifik',
+ 'category' => 'Virus / Parasit',
+ 'symptoms' => ['Diare', 'Lemas', 'Nafsu makan menurun', 'Dehidrasi ringan'],
+ 'weight' => 2,
+ ],
+ [
+ 'name' => 'Earmite',
+ 'category' => 'Parasit',
+ 'symptoms' => ['Telinga kotor', 'Sering menggaruk telinga', 'Bau telinga', 'Kepala sering digelengkan'],
+ 'weight' => 2,
+ ],
+ ];
+
+ $areas = [
+ 'Sumbersari',
+ 'Kaliwates',
+ 'Patrang',
+ 'Ajung',
+ 'Rambipuji',
+ 'Ambulu',
+ 'Puger',
+ 'Wuluhan',
+ 'Arjasa',
+ 'Jenggawah',
+ ];
+
+ $cats = [
+ ['owner' => 'Alya Pratama', 'cat' => 'Milo', 'gender' => 'Jantan', 'breed' => 'Domestik'],
+ ['owner' => 'Bima Santoso', 'cat' => 'Luna', 'gender' => 'Betina', 'breed' => 'Persia'],
+ ['owner' => 'Citra Dewi', 'cat' => 'Oyen', 'gender' => 'Jantan', 'breed' => 'Domestik'],
+ ['owner' => 'Dani Kurniawan', 'cat' => 'Mochi', 'gender' => 'Betina', 'breed' => 'Anggora'],
+ ['owner' => 'Eka Lestari', 'cat' => 'Nala', 'gender' => 'Betina', 'breed' => 'Mixdom'],
+ ['owner' => 'Farhan Hakim', 'cat' => 'Simba', 'gender' => 'Jantan', 'breed' => 'Persia Medium'],
+ ['owner' => 'Gita Maharani', 'cat' => 'Coco', 'gender' => 'Betina', 'breed' => 'Domestik'],
+ ['owner' => 'Hendra Wijaya', 'cat' => 'Leo', 'gender' => 'Jantan', 'breed' => 'Maine Coon Mix'],
+ ['owner' => 'Intan Permata', 'cat' => 'Mimi', 'gender' => 'Betina', 'breed' => 'Domestik'],
+ ['owner' => 'Joko Saputra', 'cat' => 'Tom', 'gender' => 'Jantan', 'breed' => 'British Shorthair Mix'],
+ ];
+
+ $weightedDiseases = [];
+ foreach ($diseases as $disease) {
+ for ($i = 0; $i < $disease['weight']; $i++) {
+ $weightedDiseases[] = $disease;
+ }
+ }
+
+ $rows = [];
+ $today = Carbon::today();
+ $rowNumber = 1;
+
+ for ($dayOffset = 0; $dayOffset < 30; $dayOffset++) {
+ $casesForDay = 1 + ($dayOffset % 4);
+
+ if (in_array($dayOffset, [0, 1, 2, 6, 13, 20], true)) {
+ $casesForDay++;
+ }
+
+ for ($case = 0; $case < $casesForDay; $case++) {
+ $cat = $cats[($rowNumber + $case) % count($cats)];
+ $disease = $weightedDiseases[($dayOffset + $case + $rowNumber) % count($weightedDiseases)];
+ $createdAt = $today
+ ->copy()
+ ->subDays($dayOffset)
+ ->setTime(8 + (($case * 3) % 10), (17 + $rowNumber) % 60, 0);
+
+ $rows[] = [
+ 'nama_pemilik' => $cat['owner'] . ' ' . str_pad((string) $rowNumber, 2, '0', STR_PAD_LEFT),
+ 'nama_kucing' => $cat['cat'],
+ 'umur_kucing' => 6 + (($rowNumber * 3) % 72),
+ 'jenis_kelamin' => $cat['gender'],
+ 'berat_badan' => 2.4 + (($rowNumber % 18) / 10),
+ 'ras_kucing' => $cat['breed'],
+ 'alamat' => $areas[($dayOffset + $case) % count($areas)],
+ 'no_telepon' => '08DUMMY' . str_pad((string) $rowNumber, 5, '0', STR_PAD_LEFT),
+ 'hasil_diagnosis' => $disease['name'],
+ 'jenis' => $disease['category'],
+ 'gejala_dipilih' => json_encode($disease['symptoms'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
+ 'created_at' => $createdAt,
+ 'updated_at' => $createdAt,
+ ];
+
+ $rowNumber++;
+ }
+ }
+
+ Biodata::query()->insert($rows);
+ }
+}
diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php
index ebe289c..b858cf9 100644
--- a/database/seeders/DatabaseSeeder.php
+++ b/database/seeders/DatabaseSeeder.php
@@ -5,6 +5,7 @@
use App\Models\User;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
+use Illuminate\Support\Facades\Hash;
class DatabaseSeeder extends Seeder
{
@@ -16,12 +17,16 @@ class DatabaseSeeder extends Seeder
public function run(): void
{
// Create Admin User
- User::create([
- 'name' => 'Admin PawMedic',
- 'email' => 'admin@pawmedic.app',
- 'password' => \Illuminate\Support\Facades\Hash::make('admin123'),
- 'email_verified_at' => now(),
- ]);
+ User::query()->updateOrCreate(
+ ['email' => 'admin@pawmedic.app'],
+ [
+ 'name' => 'Admin PawMedic',
+ 'password' => Hash::make('admin123'),
+ 'email_verified_at' => now(),
+ ]
+ );
+
+ $this->call(BiodataTrendSeeder::class);
// Optional: Create test user
// User::factory()->create([
diff --git a/public/data/Bissmilah lagi.xlsx b/public/data/Bissmilah lagi.xlsx
index 6875280..2710d82 100644
Binary files a/public/data/Bissmilah lagi.xlsx and b/public/data/Bissmilah lagi.xlsx differ
diff --git a/python_api/app.py b/python_api/app.py
index 948f2a3..fea2b95 100644
--- a/python_api/app.py
+++ b/python_api/app.py
@@ -11,7 +11,7 @@ app = Flask(__name__)
model = joblib.load("../python_artifacts/model.joblib")
# =========================
-# LOAD FEATURE
+# LOAD FEATURE/GEJALA
# =========================
with open("../python_artifacts/feature_cols.json") as f:
feature_cols = json.load(f)
@@ -66,7 +66,7 @@ def predict():
print("INPUT VECTOR:", input_data)
input_df = pd.DataFrame([input_data], columns=feature_cols)
-
+#melakukan prediksi
hasil = model.predict(input_df)[0]
penyakit = str(hasil).lower().strip()
@@ -82,7 +82,7 @@ def predict():
"pertolongan": [],
"pencegahan": []
})
-
+#mengembalikan hasil prediksi ke laravel
return jsonify({
"penyakit": hasil,
"jenis": info["jenis"],
diff --git a/resources/views/biodata.blade.php b/resources/views/biodata.blade.php
index 2b879b6..3893d72 100644
--- a/resources/views/biodata.blade.php
+++ b/resources/views/biodata.blade.php
@@ -159,6 +159,71 @@
font-size:13px;
}
+.combo-wrap{
+ position:relative;
+}
+.combo-input-wrap{
+ position:relative;
+}
+.combo-input-wrap input{
+ padding-right:46px;
+}
+.combo-toggle{
+ position:absolute;
+ right:14px;
+ top:50%;
+ transform:translateY(-50%);
+ border:none;
+ background:transparent;
+ color:#334155;
+ width:28px;
+ height:28px;
+ display:flex;
+ align-items:center;
+ justify-content:center;
+ cursor:pointer;
+ font-size:14px;
+}
+.combo-menu{
+ display:none;
+ position:absolute;
+ left:0;
+ right:0;
+ top:calc(100% + 8px);
+ z-index:20;
+ max-height:240px;
+ overflow:auto;
+ padding:8px;
+ border:1px solid #dbe6ef;
+ border-radius:14px;
+ background:#fff;
+ box-shadow:0 18px 44px rgba(15,23,42,0.16);
+}
+.combo-wrap.open .combo-menu{
+ display:block;
+}
+.combo-option{
+ width:100%;
+ border:none;
+ background:transparent;
+ color:var(--text-dark);
+ padding:11px 12px;
+ border-radius:10px;
+ text-align:left;
+ font:600 14px var(--ff-body);
+ cursor:pointer;
+}
+.combo-option:hover,
+.combo-option.active{
+ background:var(--primary-light);
+ color:var(--primary-dark);
+}
+.combo-empty{
+ padding:12px;
+ color:var(--text-muted);
+ font-size:14px;
+}
+
.form-row{
display:grid;
grid-template-columns:1fr 1fr;
@@ -343,7 +408,7 @@
diff --git a/resources/views/gejala.blade.php b/resources/views/gejala.blade.php
index c8b2d90..2983cc3 100644
--- a/resources/views/gejala.blade.php
+++ b/resources/views/gejala.blade.php
@@ -5,6 +5,7 @@
Pilih Gejala - PawMedic
+
@@ -205,7 +206,7 @@
animation:fadeUp 0.8s cubic-bezier(0.16, 1, 0.3, 1);
border:1px solid rgba(111,207,151,0.2);
position:relative;
- overflow:hidden;
+ overflow:visible;
transform-style:preserve-3d;
transition:transform 0.3s ease, box-shadow 0.3s ease;
}
@@ -237,6 +238,7 @@
}
.form-card::after{
+ display:none;
content:'';
position:absolute;
top:-50%;
@@ -378,6 +380,9 @@
position:relative;
animation:fadeInUp 0.5s ease backwards;
}
+.gejala-item:hover{
+ z-index:5;
+}
.gejala-item:nth-child(1){animation-delay:0.05s;}
.gejala-item:nth-child(2){animation-delay:0.1s;}
@@ -409,6 +414,7 @@
.gejala-label{
display:flex;
align-items:center;
+ flex-wrap:wrap;
gap:14px;
padding:20px 24px;
background:linear-gradient(135deg, #ffffff 0%, #fafafa 100%);
@@ -421,40 +427,20 @@
color:var(--text-dark);
user-select:none;
position:relative;
- overflow:hidden;
+ overflow:visible;
box-shadow:
0 4px 12px rgba(0,0,0,0.06),
0 0 0 0 rgba(111,207,151,0);
transform:perspective(1000px) rotateX(0deg);
}
-.gejala-label::after{
- content:'';
- position:absolute;
- top:50%;
- left:50%;
- width:0;
- height:0;
- border-radius:50%;
- background:rgba(111,207,151,0.1);
- transform:translate(-50%, -50%);
- transition:width 0.6s ease, height 0.6s ease;
-}
-
-.gejala-label:hover::after{
- width:300px;
- height:300px;
-}
-
.gejala-label:hover{
background:linear-gradient(135deg, var(--primary-light) 0%, #ffffff 100%);
border-color:var(--primary);
- transform:translateY(-6px) scale(1.03) perspective(1000px) rotateX(-2deg);
+ transform:translateY(-3px);
box-shadow:
- 0 12px 32px rgba(111,207,151,0.25),
- 0 0 0 4px rgba(111,207,151,0.1),
- inset 0 1px 0 rgba(255,255,255,0.9);
- border-width:3px;
+ 0 10px 24px rgba(111,207,151,0.18),
+ 0 0 0 4px rgba(111,207,151,0.08);
}
.gejala-checkbox:checked + .gejala-label{
@@ -466,23 +452,7 @@
0 12px 36px rgba(111,207,151,0.3),
0 0 0 5px rgba(111,207,151,0.15),
inset 0 2px 4px rgba(111,207,151,0.1);
- transform:translateY(-4px) scale(1.02) perspective(1000px) rotateX(-1deg);
- animation:selectedPulse 2s ease infinite;
-}
-
-@keyframes selectedPulse{
- 0%, 100%{
- box-shadow:
- 0 12px 36px rgba(111,207,151,0.3),
- 0 0 0 5px rgba(111,207,151,0.15),
- inset 0 2px 4px rgba(111,207,151,0.1);
- }
- 50%{
- box-shadow:
- 0 12px 36px rgba(111,207,151,0.35),
- 0 0 0 6px rgba(111,207,151,0.2),
- inset 0 2px 4px rgba(111,207,151,0.15);
- }
+ transform:translateY(-2px);
}
.gejala-checkbox:checked + .gejala-label::before{
@@ -527,6 +497,156 @@
z-index:1;
}
+.gejala-name{
+ position:relative;
+ z-index:2;
+ flex:1;
+ min-width:0;
+}
+
+.gejala-help{
+ position:relative;
+ z-index:3;
+ width:28px;
+ height:28px;
+ border-radius:999px;
+ display:inline-flex;
+ align-items:center;
+ justify-content:center;
+ color:var(--primary-dark);
+ background:#ecfdf5;
+ border:1px solid #bbf7d0;
+ flex-shrink:0;
+}
+
+.gejala-help i{
+ transition:transform 0.2s ease;
+}
+
+.gejala-item.show-info .gejala-help i{
+ transform:rotate(180deg);
+}
+
+.gejala-description{
+ display:none;
+ width:100%;
+ margin-top:2px;
+ margin-left:42px;
+ padding:12px 14px;
+ border-radius:12px;
+ background:#f0fdf4;
+ border:1px solid #bbf7d0;
+ color:#14532d;
+ font-size:13px;
+ line-height:1.55;
+ font-weight:500;
+}
+.gejala-item.show-info .gejala-description{
+ display:block;
+}
+
+.diagnosis-alert{
+ display:none;
+ position:fixed;
+ left:50%;
+ top:50%;
+ z-index:9999;
+ width:min(420px, calc(100vw - 28px));
+ margin:0;
+ padding:16px 44px 16px 16px;
+ border:1px solid #fde68a;
+ border-radius:14px;
+ background:#ffffff;
+ color:#1f2937;
+ box-shadow:0 22px 55px rgba(15,23,42,0.26);
+ transform:translate(-50%, -46%) scale(.96);
+ opacity:0;
+ transition:opacity .2s ease, transform .2s ease;
+}
+
+.diagnosis-alert.show{
+ display:flex;
+ align-items:flex-start;
+ gap:12px;
+ opacity:1;
+ transform:translate(-50%, -50%) scale(1);
+}
+
+.diagnosis-alert-icon{
+ flex:0 0 auto;
+ width:36px;
+ height:36px;
+ border-radius:50%;
+ display:inline-flex;
+ align-items:center;
+ justify-content:center;
+ color:#b45309;
+ background:#fef3c7;
+ font-size:18px;
+}
+
+.diagnosis-alert-content{
+ min-width:0;
+}
+
+.diagnosis-alert-heading{
+ display:block;
+ margin:0 0 2px;
+ color:#114d3a;
+ font-size:14px;
+ font-weight:800;
+ line-height:1.35;
+}
+
+.diagnosis-alert-message{
+ margin:0;
+ color:#475569;
+ font-size:14px;
+ font-weight:600;
+ line-height:1.45;
+}
+
+.diagnosis-alert-close{
+ position:absolute;
+ top:12px;
+ right:10px;
+ width:28px;
+ height:28px;
+ border:0;
+ border-radius:50%;
+ display:inline-flex;
+ align-items:center;
+ justify-content:center;
+ color:#64748b;
+ background:transparent;
+ cursor:pointer;
+ transition:background .2s ease, color .2s ease;
+}
+
+.diagnosis-alert-close:hover{
+ color:#0f172a;
+ background:#f1f5f9;
+}
+
+@media (max-width:480px){
+ .diagnosis-alert{
+ width:calc(100vw - 24px);
+ padding:14px 40px 14px 14px;
+ border-radius:12px;
+ }
+
+ .diagnosis-alert-icon{
+ width:32px;
+ height:32px;
+ font-size:16px;
+ }
+
+ .diagnosis-alert-heading,
+ .diagnosis-alert-message{
+ font-size:13px;
+ }
+}
+
.selected-count{
background:linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
color:white;
@@ -826,6 +946,65 @@ class="search-input"
✕
+ @php
+ $explainGejala = function ($name) {
+ $text = trim((string) $name);
+ $lower = \Illuminate\Support\Str::lower($text);
+ $rules = [
+ 'demam tinggi' => 'Telinga, telapak kaki, atau tubuh kucing terasa lebih panas dari biasanya dan kucing tampak kurang aktif.',
+ 'sulit kencing' => 'Cek litterbox/kotak pasir kucing, lihat apakah kencingnya sedikit atau normal ke banyak.',
+ 'kencing' => 'Amati frekuensi, jumlah, warna, dan apakah kucing tampak mengejan saat menggunakan kotak pasir.',
+ 'diare berdarah' => 'Periksa apakah feses encer bercampur darah. Jika terlihat darah, kondisi ini perlu lebih diwaspadai.',
+ 'diare' => 'Periksa apakah feses lebih encer dari biasanya, lebih sering keluar, atau baunya lebih menyengat.',
+ 'muntah' => 'Catat seberapa sering kucing muntah, isi muntahan, dan apakah terjadi setelah makan atau minum.',
+ 'nafsu makan' => 'Bandingkan porsi makan hari ini dengan kebiasaan normalnya dan perhatikan apakah kucing menolak makanan favorit.',
+ 'kelemahan' => 'Perhatikan apakah kucing tampak lemas, lebih banyak diam, sulit berdiri, atau tidak mau bermain.',
+ 'lemas' => 'Perhatikan apakah kucing lebih banyak tidur, kurang responsif, atau enggan bermain dan bergerak.',
+ 'bersin' => 'Amati apakah bersin disertai lendir hidung, mata berair, atau napas berbunyi.',
+ 'flu' => 'Perhatikan apakah hidung berair, bersin, atau kucing terlihat sulit mencium makanan.',
+ 'pilek' => 'Cek apakah ada cairan dari hidung, hidung tersumbat, atau suara napas menjadi berbeda.',
+ 'sesak napas' => 'Lihat apakah napas kucing cepat, berat, mulut terbuka, atau dada terlihat naik turun kuat.',
+ 'batuk' => 'Dengarkan apakah batuk kering atau berdahak, serta apakah muncul setelah aktivitas atau saat istirahat.',
+ 'radang telinga' => 'Cek apakah telinga kemerahan, kotor, berbau, atau kucing sering menggaruk telinga.',
+ 'otitis' => 'Perhatikan apakah kucing sering menggelengkan kepala, telinga berbau, atau ada kotoran berlebih.',
+ 'gatal' => 'Cek area kulit yang sering digaruk, dijilat, atau digigit, terutama telinga, leher, punggung, dan ekor.',
+ 'kutu' => 'Sisir atau buka bulu kucing dan lihat apakah ada kutu kecil bergerak atau bintik hitam seperti kotoran.',
+ 'pinjal' => 'Periksa pangkal ekor, leher, dan perut untuk melihat kutu kecil atau bekas gigitan.',
+ 'kebotakan' => 'Lihat apakah ada area bulu yang menipis atau botak, terutama jika sering digaruk atau dijilat.',
+ 'rontok' => 'Perhatikan apakah bulu rontok lebih banyak dari biasanya atau menyisakan area kulit terlihat.',
+ 'bulu' => 'Lihat apakah bulu rontok berlebihan, kusam, menggumpal, atau ada area botak.',
+ 'gangguan mata' => 'Periksa apakah mata merah, berair, belekan, bengkak, atau kucing sering menyipitkan mata.',
+ 'mata' => 'Perhatikan apakah mata terlihat keruh, merah, berair, atau ada kotoran yang tidak biasa.',
+ 'telinga' => 'Cek apakah telinga kotor, berbau, sering digaruk, atau kepala sering digelengkan.',
+ 'demam' => 'Rasakan telinga/telapak kaki yang lebih hangat dari biasa dan perhatikan apakah kucing tampak lesu.',
+ 'luka pada mulut' => 'Lihat area gusi, lidah, atau bibir. Perhatikan apakah ada sariawan, luka, bau mulut, atau sulit makan.',
+ 'luka garukan' => 'Cek bekas garukan, kemerahan, atau kerak di kulit akibat kucing sering menggaruk.',
+ 'luka' => 'Periksa lokasi luka, kemerahan, bengkak, nanah, atau apakah kucing kesakitan saat disentuh.',
+ 'pincang' => 'Amati cara berjalan kucing, apakah salah satu kaki diangkat, diseret, atau tidak kuat menapak.',
+ 'selaput lendir kuning' => 'Cek gusi, bagian putih mata, atau telinga bagian dalam. Warna kuning bisa menandakan masalah serius.',
+ 'jaundice' => 'Perhatikan warna kuning pada gusi, mata, atau kulit tipis seperti telinga.',
+ 'perut membesar' => 'Lihat apakah perut tampak membesar tidak biasa, terasa tegang, atau kucing tidak nyaman saat disentuh.',
+ 'buncit' => 'Bandingkan bentuk perut dengan biasanya, terutama jika disertai lemas atau nafsu makan turun.',
+ 'anemia' => 'Cek warna gusi. Gusi yang tampak pucat bisa menjadi tanda darah atau stamina kucing sedang bermasalah.',
+ 'infeksi kulit' => 'Periksa kulit yang merah, basah, berkerak, bernanah, atau berbau tidak biasa.',
+ 'overgrooming' => 'Perhatikan apakah kucing menjilat satu area terus-menerus sampai bulu menipis atau kulit iritasi.',
+ 'perut bawah keras' => 'Raba pelan area perut bawah. Jika terasa keras dan kucing kesakitan, catat sebagai gejala penting.',
+ 'sakit perut' => 'Perhatikan apakah kucing menghindar saat perut disentuh, meringkuk, atau tampak tidak nyaman.',
+ 'nyeri abdomen' => 'Amati tanda nyeri di perut seperti mengeong saat disentuh, gelisah, atau posisi tubuh membungkuk.',
+ 'penurunan berat badan cepat' => 'Bandingkan berat atau bentuk tubuh dalam beberapa hari/minggu terakhir, terutama jika makan tetap normal.',
+ 'berat' => 'Bandingkan berat badan dengan kondisi sebelumnya dan amati apakah tubuh tampak lebih kurus atau membesar.',
+ ];
+
+ foreach ($rules as $keyword => $description) {
+ if (\Illuminate\Support\Str::contains($lower, $keyword)) {
+ return $description;
+ }
+ }
+
+ return 'Perhatikan gejala ' . $text . ' dengan melihat kapan mulai muncul, seberapa sering terjadi, dan apakah membuat kucing berubah perilaku.';
+ };
+ @endphp
+
@foreach($gejala as $item)
@@ -837,7 +1016,11 @@ class="gejala-checkbox"
id="gejala_{{ $loop->index }}"
>
- {{ $item }}
+ {{ $item }}
+
+
+
+ {{ $explainGejala($item) }}
@endforeach
@@ -858,6 +1041,19 @@ class="gejala-checkbox"
+
+
+
+
+
+
Perhatian
+
Pilih minimal 4 gejala terlebih dahulu.
+
+
+
+
+
+
@include('components.toast')
@include('components.scroll-top')
@@ -866,6 +1062,24 @@ class="gejala-checkbox"
const submitBtn = document.getElementById('submitBtn');
const selectedCount = document.getElementById('selectedCount');
const form = document.getElementById('gejalaForm');
+const diagnosisAlert = document.getElementById('diagnosisAlert');
+const diagnosisAlertText = document.getElementById('diagnosisAlertText');
+const closeDiagnosisAlert = document.getElementById('closeDiagnosisAlert');
+let diagnosisAlertTimer = null;
+
+function showDiagnosisAlert(message) {
+ diagnosisAlertText.textContent = message;
+ diagnosisAlert.classList.add('show');
+ clearTimeout(diagnosisAlertTimer);
+ diagnosisAlertTimer = setTimeout(hideDiagnosisAlert, 3000);
+}
+
+function hideDiagnosisAlert() {
+ clearTimeout(diagnosisAlertTimer);
+ diagnosisAlert.classList.remove('show');
+}
+
+closeDiagnosisAlert.addEventListener('click', hideDiagnosisAlert);
function updateSelectedCount() {
const checked = document.querySelectorAll('.gejala-checkbox:checked').length;
@@ -875,13 +1089,13 @@ function updateSelectedCount() {
selectedCount.classList.add('animate');
setTimeout(() => selectedCount.classList.remove('animate'), 500);
- // Enable/disable submit button
+ // Tombol tetap bisa diklik agar validasi menampilkan alert yang jelas.
if (checked >= 4 && checked <= 7) {
- submitBtn.disabled = false;
submitBtn.style.opacity = '1';
+ submitBtn.setAttribute('aria-disabled', 'false');
} else {
- submitBtn.disabled = true;
submitBtn.style.opacity = '0.6';
+ submitBtn.setAttribute('aria-disabled', 'true');
}
}
@@ -890,6 +1104,23 @@ function updateSelectedCount() {
checkbox.addEventListener('change', updateSelectedCount);
});
+document.querySelectorAll('.gejala-help').forEach((help) => {
+ const item = help.closest('.gejala-item');
+ const toggleInfo = (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ const isOpen = item.classList.toggle('show-info');
+ help.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
+ };
+
+ help.addEventListener('click', toggleInfo);
+ help.addEventListener('keydown', (event) => {
+ if (event.key === 'Enter' || event.key === ' ') {
+ toggleInfo(event);
+ }
+ });
+});
+
// Form submission
form.addEventListener('submit', function(e) {
@@ -898,15 +1129,17 @@ function updateSelectedCount() {
const checked = document.querySelectorAll('.gejala-checkbox:checked');
if (checked.length < 4) {
- alert("Minimal pilih 4 gejala!");
+ showDiagnosisAlert("Minimal pilih 4 gejala sebelum melanjutkan diagnosis.");
return;
}
if (checked.length > 7) {
- alert("Maksimal hanya 7 gejala!");
+ showDiagnosisAlert("Maksimal hanya 7 gejala yang dapat dipilih.");
return;
}
+ hideDiagnosisAlert();
+
// ambil gejala
let gejala = [];
checked.forEach(c => gejala.push(c.value));
diff --git a/resources/views/landing.blade.php b/resources/views/landing.blade.php
index 5975f67..fcf8663 100644
--- a/resources/views/landing.blade.php
+++ b/resources/views/landing.blade.php
@@ -17,6 +17,9 @@
--ff-body: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial;
--space:28px;
--muted: #6b7280;
+ --primary: #6fcf97;
+ --primary-dark: #4bb66f;
+ --primary-light: #e8f7ef;
}
body{
margin:0;
@@ -292,6 +295,299 @@
transform:translateY(-6px);
}
+/* ===== HEALTH TRENDS ===== */
+.health-trends{
+ background:linear-gradient(135deg,#ffffff 0%,#f8fffb 58%,#f6fbff 100%);
+ border:1px solid rgba(111,207,151,0.18);
+ border-radius:22px;
+ padding:26px;
+ box-shadow:0 16px 46px rgba(17,77,58,0.08);
+}
+.trend-heading{
+ display:flex;
+ align-items:center;
+ justify-content:space-between;
+ gap:18px;
+ flex-wrap:wrap;
+ margin-bottom:20px;
+}
+.trend-title-wrap{
+ display:flex;
+ align-items:flex-start;
+ gap:18px;
+}
+.trend-title-icon{
+ width:48px;
+ height:48px;
+ border-radius:14px;
+ background:linear-gradient(135deg,#dcfce7,#f0fdf4);
+ display:flex;
+ align-items:center;
+ justify-content:center;
+ color:#0f5132;
+ font-size:22px;
+ box-shadow:0 10px 26px rgba(34,197,94,0.13);
+}
+.trend-heading h2{
+ text-align:left;
+ margin-bottom:6px;
+ font-size:clamp(1.7rem, 3vw, 2.35rem);
+ color:#064e3b;
+}
+.trend-heading p{
+ text-align:left;
+ margin:0;
+ max-width:680px;
+ color:#64748b;
+}
+.trend-filter{
+ display:inline-flex;
+ gap:6px;
+ background:#f8fafc;
+ border:1px solid #e2e8f0;
+ border-radius:14px;
+ padding:6px;
+ box-shadow:inset 0 1px 3px rgba(15,23,42,0.05);
+}
+.trend-filter a{
+ text-decoration:none;
+ color:#475569;
+ font-weight:700;
+ font-size:14px;
+ padding:9px 18px;
+ border-radius:10px;
+ white-space:nowrap;
+}
+.trend-filter a.active{
+ background:linear-gradient(135deg,#22c55e,#16a34a);
+ color:#fff;
+ box-shadow:0 8px 18px rgba(34,197,94,0.24);
+}
+.trend-grid{
+ display:grid;
+ grid-template-columns:minmax(0,1fr) minmax(0,1fr);
+ gap:18px;
+}
+.trend-panel{
+ background:rgba(255,255,255,0.75);
+ border:1px solid #cfead9;
+ border-radius:18px;
+ padding:18px;
+ min-height:310px;
+ box-shadow:inset 0 1px 0 rgba(255,255,255,0.8);
+}
+.trend-panel.area-panel{
+ border-color:#c7daf9;
+ background:
+ radial-gradient(circle at 20% 20%, rgba(59,130,246,0.09), transparent 34%),
+ linear-gradient(145deg, rgba(255,255,255,0.9), rgba(248,251,255,0.78));
+}
+.trend-panel h3{
+ font-size:18px;
+ margin-bottom:10px;
+ display:flex;
+ align-items:center;
+ gap:12px;
+}
+.trend-panel h3 i{
+ width:38px;
+ height:38px;
+ border-radius:12px;
+ display:inline-flex;
+ align-items:center;
+ justify-content:center;
+ background:#dcfce7;
+ color:#16a34a;
+ font-size:22px;
+}
+.trend-panel.area-panel h3 i{
+ background:#dbeafe;
+ color:#2563eb;
+}
+.trend-panel p{
+ color:#64748b;
+ margin:0 0 14px;
+ font-size:14px;
+}
+.trend-chart-wrap{
+ height:205px;
+}
+.disease-legend{
+ display:none;
+ grid-template-columns:1fr 1fr;
+ gap:8px 24px;
+ border:1px solid #d7eadf;
+ border-radius:16px;
+ padding:14px 18px;
+ margin-top:18px;
+ background:rgba(255,255,255,0.72);
+}
+.legend-row{
+ display:grid;
+ grid-template-columns:auto 1fr auto;
+ align-items:center;
+ gap:10px;
+ color:#475569;
+ font-size:13px;
+}
+.legend-dot{
+ width:10px;
+ height:10px;
+ border-radius:999px;
+ background:#22c55e;
+}
+.legend-total{
+ color:#0f172a;
+ font-weight:800;
+}
+.area-donut-layout{
+ display:grid;
+ grid-template-columns:minmax(180px, 0.95fr) minmax(190px, 1fr);
+ align-items:center;
+ gap:22px;
+ margin-top:10px;
+}
+.area-donut-wrap{
+ height:220px;
+ position:relative;
+ padding:8px;
+ border-radius:999px;
+ background:radial-gradient(circle at 50% 50%, #ffffff 0%, #ffffff 42%, rgba(219,234,254,0.55) 43%, rgba(255,255,255,0) 70%);
+}
+.area-list{
+ display:flex;
+ flex-direction:column;
+ gap:12px;
+}
+.area-row{
+ display:grid;
+ grid-template-columns:auto 1fr auto;
+ align-items:center;
+ gap:12px;
+ border:1px solid #dbe5f2;
+ border-radius:14px;
+ background:rgba(255,255,255,0.78);
+ padding:13px 16px;
+ color:#334155;
+}
+.area-dot{
+ width:18px;
+ height:18px;
+ border-radius:999px;
+ background:#2563eb;
+}
+.area-count{
+ color:#2563eb;
+ font-weight:800;
+}
+.trend-bottom-grid{
+ margin-top:18px;
+ display:grid;
+ grid-template-columns:0.8fr 1.2fr 1.2fr;
+ gap:16px;
+}
+.trend-empty{
+ min-height:210px;
+ display:flex;
+ align-items:center;
+ justify-content:center;
+ text-align:center;
+ color:#64748b;
+ background:#f8fafc;
+ border-radius:12px;
+ padding:20px;
+}
+.trend-highlight{
+ background:linear-gradient(135deg,#dcfce7 0%,#f7fffb 100%);
+ border:1px solid #74d99b;
+ border-radius:18px;
+ padding:24px;
+ display:flex;
+ align-items:center;
+ gap:20px;
+ min-height:130px;
+ position:relative;
+ overflow:hidden;
+}
+.trend-highlight::after{
+ content:'';
+ position:absolute;
+ right:22px;
+ bottom:14px;
+ width:96px;
+ height:96px;
+ opacity:0.12;
+ background:linear-gradient(135deg,#16a34a,#86efac);
+ clip-path:polygon(46% 100%,46% 54%,10% 54%,10% 34%,68% 34%,68% 0,100% 50%,68% 100%,68% 68%,58% 68%,58% 100%);
+}
+.trend-highlight-icon,
+.care-icon{
+ width:52px;
+ height:52px;
+ border-radius:999px;
+ display:flex;
+ align-items:center;
+ justify-content:center;
+ flex-shrink:0;
+ font-size:24px;
+ color:#fff;
+}
+.trend-highlight-icon{
+ background:linear-gradient(135deg,#fb923c,#f97316);
+ box-shadow:0 12px 26px rgba(249,115,22,0.22);
+}
+.trend-highlight span{
+ display:block;
+ color:#64748b;
+ font-size:13px;
+ font-weight:700;
+ text-transform:uppercase;
+ letter-spacing:0.04em;
+ margin-bottom:6px;
+}
+.trend-highlight strong{
+ display:block;
+ color:#114d3a;
+ font-family:var(--ff-heading);
+ font-size:19px;
+ line-height:1.35;
+}
+.care-box{
+ background:rgba(255,255,255,0.78);
+ border:1px solid #facc15;
+ border-radius:18px;
+ padding:20px;
+ display:flex;
+ gap:16px;
+ min-height:130px;
+}
+.care-box.prevention{
+ border-color:#c4a4f3;
+}
+.care-box.handling .care-icon{
+ background:linear-gradient(135deg,#facc15,#f59e0b);
+ box-shadow:0 12px 26px rgba(245,158,11,0.2);
+}
+.care-box.prevention .care-icon{
+ background:linear-gradient(135deg,#a78bfa,#7c3aed);
+ box-shadow:0 12px 26px rgba(124,58,237,0.18);
+}
+.care-box h3{
+ font-size:19px;
+ margin-bottom:10px;
+}
+.care-box p,
+.care-box ul{
+ margin:0;
+ color:#334155;
+}
+.care-box ul{
+ padding-left:18px;
+}
+.care-box li + li{
+ margin-top:8px;
+}
+
/* ===== FEATURES ===== */
.features{
display:grid;
@@ -574,6 +870,11 @@
.features{
grid-template-columns:repeat(2,1fr);
}
+ .trend-grid,
+ .trend-bottom-grid,
+ .area-donut-layout{
+ grid-template-columns:1fr;
+ }
section{
margin-top:72px;
}
@@ -625,6 +926,54 @@
.features{
grid-template-columns:1fr;
}
+ .health-trends{
+ padding:16px 12px;
+ border-radius:12px;
+ }
+ .trend-heading h2{
+ font-size:22px;
+ }
+ .trend-filter{
+ width:100%;
+ }
+ .trend-filter a{
+ flex:1;
+ text-align:center;
+ font-size:13px;
+ padding:8px;
+ }
+ .trend-panel{
+ padding:14px;
+ min-height:280px;
+ }
+ .trend-title-wrap{
+ gap:12px;
+ }
+ .trend-title-icon{
+ width:46px;
+ height:46px;
+ font-size:22px;
+ }
+ .trend-chart-wrap{
+ height:220px;
+ }
+ .disease-legend{
+ grid-template-columns:1fr;
+ }
+ .trend-highlight,
+ .care-box{
+ padding:16px;
+ align-items:flex-start;
+ }
+ .trend-highlight-icon,
+ .care-icon{
+ width:48px;
+ height:48px;
+ font-size:22px;
+ }
+ .trend-highlight strong{
+ font-size:18px;
+ }
.hero-content h2{
font-size:20px;
line-height:1.3;
@@ -768,6 +1117,115 @@
+
+
+
+
+
+
+
Penyakit Terbanyak
+
+ Ringkasan kasus diagnosis dari data PawMedic pada periode {{ $diseaseNews['period_label'] ?? '30 hari terakhir' }}
+ ({{ $diseaseNews['start_label'] ?? '-' }} - {{ $diseaseNews['end_label'] ?? '-' }}).
+
+
+
+
+
+
+ @if(!empty($diseaseNews['top_disease']))
+
+
+
Kasus per Penyakit
+
Penyakit yang paling sering muncul berdasarkan hasil diagnosis pengguna.
+
+
+
+
+ @foreach(($diseaseNews['disease_labels'] ?? collect()) as $index => $label)
+
+
+ {{ $label }}
+ {{ ($diseaseNews['disease_data'] ?? collect())[$index] ?? 0 }}
+
+ @endforeach
+
+
+
+
Daerah Kasus {{ $diseaseNews['top_disease'] }}
+
Wilayah terbanyak untuk penyakit tertinggi pada periode yang dipilih.
+ @if(($diseaseNews['area_data'] ?? collect())->count() > 0)
+
+
+
+
+
+ @foreach(($diseaseNews['area_labels'] ?? collect()) as $index => $label)
+
+
+ {{ $label }}
+ {{ ($diseaseNews['area_data'] ?? collect())[$index] ?? 0 }} kasus
+
+ @endforeach
+
+
+ @else
+
Belum ada data alamat yang cukup untuk penyakit ini.
+ @endif
+
+
+
+
+
+
+
+
Kasus tertinggi
+
{{ $diseaseNews['top_disease'] }}
+
+ {{ $diseaseNews['total_cases'] ?? 0 }} kasus pada {{ $diseaseNews['period_label'] ?? 'periode ini' }}.
+
+
+
+
+
+
+
Penanganan
+ @if(!empty($diseaseNews['handling']))
+
+ @foreach($diseaseNews['handling'] as $item)
+ {{ $item }}
+ @endforeach
+
+ @else
+
Data penanganan belum tersedia untuk penyakit ini.
+ @endif
+
+
+
+
+
+
Pencegahan
+ @if(!empty($diseaseNews['prevention']))
+
+ @foreach($diseaseNews['prevention'] as $item)
+ {{ $item }}
+ @endforeach
+
+ @else
+
Data pencegahan belum tersedia untuk penyakit ini.
+ @endif
+
+
+
+ @else
+
+ Belum ada data diagnosis pada periode ini. Grafik akan otomatis tampil setelah data tersedia.
+
+ @endif
+
@@ -871,6 +1329,133 @@ function scrollToSection(id){
});
}
+
+