diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php index 42a0891..6415873 100644 --- a/app/Http/Controllers/AdminController.php +++ b/app/Http/Controllers/AdminController.php @@ -7,6 +7,9 @@ use Illuminate\Support\Facades\Hash; use App\Models\Biodata; use Carbon\Carbon; +use Carbon\CarbonPeriod; +use App\Models\Ulasan; +use Illuminate\Support\Facades\DB; class AdminController extends Controller { @@ -39,15 +42,29 @@ public function authenticate(Request $request) public function dashboard() { + // total diagnosis $totalDiagnosis = Biodata::count(); // hari ini $todayDiagnosis = Biodata::whereDate('created_at', Carbon::today())->count(); + // kemarin + $yesterday = Biodata::whereDate('created_at', Carbon::yesterday())->count(); + $diff = $todayDiagnosis - $yesterday; + // total user $totalUsers = Biodata::count(); + // user list + $sort = request('sort'); + +if ($sort == 'oldest') { + $data = Biodata::orderBy('created_at', 'asc')->get(); +} else { + $data = Biodata::orderBy('created_at', 'desc')->get(); +} + // penyakit paling umum $mostCommon = Biodata::select('hasil_diagnosis') ->whereNotNull('hasil_diagnosis') @@ -55,13 +72,20 @@ public function dashboard() ->orderByRaw('COUNT(*) DESC') ->value('hasil_diagnosis'); + // penyakit terbanyak hari ini + $todayDisease = Biodata::whereDate('created_at', Carbon::today()) + ->select('hasil_diagnosis') + ->whereNotNull('hasil_diagnosis') + ->groupBy('hasil_diagnosis') + ->orderByRaw('COUNT(*) DESC') + ->value('hasil_diagnosis'); + // diagnosis terbaru $recent = Biodata::select('hasil_diagnosis', 'created_at') ->latest() ->take(5) ->get(); - // format tabel $recentFormatted = $recent->map(function ($item) { return [ 'date' => $item->created_at, @@ -70,7 +94,7 @@ public function dashboard() ]; }); - // 🔥 CHART (HARUS DI LUAR MAP) + // chart penyakit $diseaseStats = Biodata::select('hasil_diagnosis') ->whereNotNull('hasil_diagnosis') ->get() @@ -82,6 +106,19 @@ public function dashboard() $chartLabels = $diseaseStats->keys()->values(); $chartData = $diseaseStats->values(); + // 🔥 7 hari terakhir + $period = CarbonPeriod::create(Carbon::now()->subDays(6), Carbon::now()); + + $dailyLabels = []; + $dailyData = []; + + foreach ($period as $date) { + $count = Biodata::whereDate('created_at', $date)->count(); + + $dailyLabels[] = $date->format('d M'); + $dailyData[] = $count; + } + // kirim ke blade $stats = [ 'total_diagnosis' => $totalDiagnosis, @@ -90,10 +127,22 @@ public function dashboard() 'most_common_disease' => $mostCommon, 'recent_diagnosis' => $recentFormatted, 'chart_labels' => $chartLabels, - 'chart_data' => $chartData + 'chart_data' => $chartData, + 'diagnosis_diff' => $diff, + 'today_top_disease' => $todayDisease, + 'daily_labels' => $dailyLabels, + 'daily_data' => $dailyData ]; + // 🔥 STAT + $ratingChart = Ulasan::select('rating', DB::raw('count(*) as total')) + ->groupBy('rating') + ->orderBy('rating') + ->get(); - return view('admin.dashboard', compact('stats')); +$stats['rating_labels'] = $ratingChart->pluck('rating'); +$stats['rating_data'] = $ratingChart->pluck('total'); + + return view('admin.dashboard', compact('stats', 'data')); } public function logout(Request $request) @@ -120,4 +169,31 @@ private function getStatistics() ] ]; } + public function statistik() +{ + $diseaseStats = Biodata::select('hasil_diagnosis') + ->whereNotNull('hasil_diagnosis') + ->get() + ->groupBy('hasil_diagnosis') + ->map(function ($item) { + return count($item); + }); + + $chartLabels = $diseaseStats->keys()->values(); + $chartData = $diseaseStats->values(); + + return view('admin.statistik', compact('chartLabels', 'chartData')); +} +public function sortDiagnosis(Request $request) +{ + $sort = $request->sort; + + if ($sort == 'oldest') { + $data = Biodata::orderBy('created_at', 'asc')->get(); + } else { + $data = Biodata::orderBy('created_at', 'desc')->get(); + } + + return response()->json($data); +} } diff --git a/app/Http/Controllers/UlasanController.php b/app/Http/Controllers/UlasanController.php new file mode 100644 index 0000000..5243638 --- /dev/null +++ b/app/Http/Controllers/UlasanController.php @@ -0,0 +1,43 @@ +get(); + // 🔥 TOTAL ULASAN + $total = $ulasan->count(); + // 🔥 RATING RATA-RATA + $avg = $ulasan->avg('rating') ?? 0; + // 🔥 5 BINTANG % + $fiveStar = $ulasan->where('rating', 5)->count(); + $fivePercent = $total > 0 ? round(($fiveStar / $total) * 100) : 0; + + return view('ulasan', compact('ulasan', 'total', 'avg', 'fivePercent')); + } + + public function store(Request $request) + { + Ulasan::create($request->all()); + + return redirect()->back()->with('success', 'Ulasan berhasil dikirim!'); + } + public function destroy($id) + { + if (!Auth::check() || Auth::user()->email !== 'admin@pawmedic.app') { + abort(403); + } + + $ulasan = Ulasan::findOrFail($id); + $ulasan->delete(); + + return redirect()->back()->with('success', 'Ulasan berhasil dihapus'); + } +} + diff --git a/app/Models/Ulasan.php b/app/Models/Ulasan.php new file mode 100644 index 0000000..1f7dd3c --- /dev/null +++ b/app/Models/Ulasan.php @@ -0,0 +1,17 @@ +id(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('ulasans'); + } +}; diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index e343b3b..4231ee7 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -145,6 +145,7 @@ display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; + margin-bottom: 30px; } .stat-card{ @@ -306,6 +307,9 @@ padding:12px 8px; } } +#chartBox { + transition: all 0.3s ease; +} @@ -341,15 +345,8 @@
-
- -
+
{{ $stats['total_diagnosis'] }}
@@ -358,6 +355,10 @@
📊
+{{ $stats['today_diagnosis'] }} hari ini
+ + Lihat Data → +
@@ -369,6 +370,19 @@
📈
Aktif hari ini
+
+ @if($stats['diagnosis_diff'] > 0) + ↑ +{{ $stats['diagnosis_diff'] }} dari kemarin + @elseif($stats['diagnosis_diff'] < 0) + ↓ {{ $stats['diagnosis_diff'] }} dari kemarin + @else + Sama dengan kemarin + @endif +
+ +
+ Terbanyak: {{ $stats['today_top_disease'] ?? '-' }} +
@@ -380,9 +394,13 @@
👥
Pengguna aktif
+ + Lihat Data → +
-
+
{{ $stats['most_common_disease'] }}
@@ -391,8 +409,112 @@
🩺
Paling sering didiagnosis
-
+ + + Lihat Data → + +
+ + + + + +
@@ -443,31 +565,237 @@
@include('components.scroll-top') + + + + + + - +function toggleUsers() { + const userBox = document.getElementById('userBox'); + const chartBox = document.getElementById('chartBox'); - + diff --git a/resources/views/admin/statistik.blade.php b/resources/views/admin/statistik.blade.php new file mode 100644 index 0000000..c3645a5 --- /dev/null +++ b/resources/views/admin/statistik.blade.php @@ -0,0 +1,20 @@ +

📊 Statistik Penyakit

+ + + + + + \ No newline at end of file diff --git a/resources/views/gejala.blade.php b/resources/views/gejala.blade.php index 2b2d19e..84adb6e 100644 --- a/resources/views/gejala.blade.php +++ b/resources/views/gejala.blade.php @@ -876,7 +876,7 @@ function updateSelectedCount() { form.addEventListener('submit', function(e) { const checked = document.querySelectorAll('.gejala-checkbox:checked').length; - if (checked < 5) { + if (checked < 4) { e.preventDefault(); alert("Minimal pilih 4 gejala!"); return; diff --git a/resources/views/landing.blade.php b/resources/views/landing.blade.php index 6ad8d6c..6a836ed 100644 --- a/resources/views/landing.blade.php +++ b/resources/views/landing.blade.php @@ -613,55 +613,25 @@

-
-
- -
+ + @csrf
- +
- +
-
- - - - - - -
+
+ + + + + +
+ +
- +
-
+
+ + @foreach($ulasan as $review) +
+
+
{{ substr($review->nama,0,1) }}
+
+
{{ $review->nama }}
+
+ {{ $review->hasil_diagnosis ?? 'Pengguna' }} +
+
+ {{ str_repeat('★', $review->rating) }} +
+
+
+ + +

{{ $review->komentar }}

+ + + @auth + @if(Auth::user()->email === 'admin@pawmedic.app') + + @csrf + @method('DELETE') + + + @endif + @endauth + +
+ {{ $review->created_at->diffForHumans() }} +
+
+ +@endforeach
@@ -559,182 +603,63 @@ @include('components.toast') @include('components.scroll-top') - + - diff --git a/routes/web.php b/routes/web.php index e8e5076..2feafca 100644 --- a/routes/web.php +++ b/routes/web.php @@ -4,11 +4,24 @@ use App\Http\Controllers\DiagnosisController; use App\Http\Controllers\AdminController; use App\Http\Controllers\GejalaController; +use App\Http\Controllers\UlasanController; +use App\Models\Ulasan; + +Route::get('/admin/sort-diagnosis', [AdminController::class, 'sortDiagnosis']); + +Route::delete('/ulasan/{id}', [UlasanController::class, 'destroy'])->name('ulasan.delete'); + +Route::get('/ulasan', [UlasanController::class, 'index'])->name('ulasan'); +Route::post('/ulasan', [UlasanController::class, 'store'])->name('ulasan.store'); Route::get('/gejala', [GejalaController::class, 'index'])->name('gejala'); +Route::delete('/admin/ulasan/{id}', [UlasanController::class, 'destroy']) + ->name('ulasan.delete'); + Route::get('/', function () { - return view('landing'); + $ulasan = Ulasan::latest()->take(3)->get(); + return view('landing', compact('ulasan')); }); Route::get('/biodata', function () { @@ -23,10 +36,6 @@ Route::get('/hasil-diagnosis', [DiagnosisController::class, 'hasil'])->name('hasil-diagnosis'); -Route::get('/ulasan', function () { - return view('ulasan'); -})->name('ulasan'); - Route::get('/faq', function () { return view('faq'); })->name('faq'); @@ -36,5 +45,5 @@ Route::post('/admin/login', [AdminController::class, 'authenticate'])->name('admin.authenticate'); Route::post('/admin/logout', [AdminController::class, 'logout'])->name('admin.logout'); Route::get('/admin/dashboard', [AdminController::class, 'dashboard'])->name('admin.dashboard')->middleware('auth'); - -Route::post('/biodata/simpan', [DiagnosisController::class, 'simpanBiodata'])->name('biodata.simpan'); \ No newline at end of file +Route::post('/biodata/simpan', [DiagnosisController::class, 'simpanBiodata'])->name('biodata.simpan'); +Route::get('/admin/statistik', [AdminController::class, 'statistik'])->name('admin.statistik'); \ No newline at end of file