diff --git a/app/Http/Controllers/Web/Dashboard/SummaryController.php b/app/Http/Controllers/Web/Dashboard/SummaryController.php index 77c4982..9326b5b 100644 --- a/app/Http/Controllers/Web/Dashboard/SummaryController.php +++ b/app/Http/Controllers/Web/Dashboard/SummaryController.php @@ -4,6 +4,12 @@ namespace App\Http\Controllers\Web\Dashboard; use App\Http\Controllers\Controller; use Illuminate\Http\Request; +use App\Models\Profile; +use App\Models\Wilayah\Provinsi; +use App\Models\wilayah\KabupatenKota; +use App\Models\Wilayah\Kecamatan; +use App\Models\Wilayah\DesaKelurahan; +use App\Models\Pertanian\Lahan; use Illuminate\Support\Facades\Gate; class SummaryController extends Controller @@ -16,4 +22,91 @@ class SummaryController extends Controller $title = 'Summary Dashboard'; return view('dashboard.summary', compact('title')); } + + public function produktivitas(Request $request) + { + if (!Gate::allows('super_admin') && !Gate::allows('admin')) { + abort(403); + } + + $title = 'Produktivitas Dashboard'; + $luasTotal = Lahan::whereNotNull('path')->sum('luas_lahan'); + $totalpetani = Profile::where('role', 'petani')->count(); + $totallahan = Lahan::whereNotNull('path')->count(); + + $petaniList = Profile::where('role', 'petani') + ->with(['lahan.tanaman.komoditas', 'desaKelurahan']) + ->paginate(20); + + $allLahan = Lahan::whereNotNull('path') + ->with(['profile', 'tanaman.komoditas', 'desaKelurahan.kecamatan.kabupatenKota.provinsi']) + ->get(); + + $geoProvinsi = []; + $geoKabupaten = []; + $geoKecamatan = []; + $geoDesa = []; + $geoLahan = []; + + foreach ($allLahan as $lahan) { + $desa = $lahan->desaKelurahan; + $kec = $desa ? $desa->kecamatan : null; + $kab = $kec ? $kec->kabupatenKota : null; + $prov = $kab ? $kab->provinsi : null; + + if ($prov && $prov->path) { + if (!isset($geoProvinsi[$prov->id])) { + $geoProvinsi[$prov->id] = ['id' => $prov->id, 'nama' => $prov->nama, 'polygon' => $prov->path, 'total_lahan' => 0, 'total_luas' => 0]; + } + $geoProvinsi[$prov->id]['total_lahan']++; + $geoProvinsi[$prov->id]['total_luas'] += $lahan->luas_lahan; + } + + if ($kab && $kab->path) { + if (!isset($geoKabupaten[$kab->id])) { + $geoKabupaten[$kab->id] = ['id' => $kab->id, 'parent_id' => $prov->id ?? null, 'nama' => $kab->nama, 'polygon' => $kab->path, 'total_lahan' => 0, 'total_luas' => 0]; + } + $geoKabupaten[$kab->id]['total_lahan']++; + $geoKabupaten[$kab->id]['total_luas'] += $lahan->luas_lahan; + } + + if ($kec && $kec->path) { + if (!isset($geoKecamatan[$kec->id])) { + $geoKecamatan[$kec->id] = ['id' => $kec->id, 'parent_id' => $kab->id ?? null, 'nama' => $kec->nama, 'polygon' => $kec->path, 'total_lahan' => 0, 'total_luas' => 0]; + } + $geoKecamatan[$kec->id]['total_lahan']++; + $geoKecamatan[$kec->id]['total_luas'] += $lahan->luas_lahan; + } + + if ($desa && $desa->path) { + if (!isset($geoDesa[$desa->id])) { + $geoDesa[$desa->id] = ['id' => $desa->id, 'parent_id' => $kec->id ?? null, 'nama' => $desa->nama, 'polygon' => $desa->path, 'total_lahan' => 0, 'total_luas' => 0]; + } + $geoDesa[$desa->id]['total_lahan']++; + $geoDesa[$desa->id]['total_luas'] += $lahan->luas_lahan; + } + + $geoLahan[] = [ + 'id' => $lahan->id, + 'parent_id' => $desa->id ?? null, + 'polygon' => $lahan->path, + 'nama_petani' => $lahan->profile->nama ?? 'N/A', + 'luas' => $lahan->luas_lahan, + 'tanaman' => $lahan->tanaman->map(fn($t) => $t->komoditas->nama ?? null)->filter()->unique()->values() + ]; + } + + return view('dashboard.produktivitas', [ + 'title' => $title, + 'petaniList' => $petaniList, + 'totalpetani' => $totalpetani, + 'totallahan' => $totallahan, + 'luasTotal' => $luasTotal, + 'geoProvinsi' => array_values($geoProvinsi), + 'geoKabupaten' => array_values($geoKabupaten), + 'geoKecamatan' => array_values($geoKecamatan), + 'geoDesa' => array_values($geoDesa), + 'geoLahan' => $geoLahan + ]); + } } diff --git a/resources/views/dashboard/dashboard.blade.php b/resources/views/dashboard/dashboard.blade.php new file mode 100644 index 0000000..24b8cb8 --- /dev/null +++ b/resources/views/dashboard/dashboard.blade.php @@ -0,0 +1,408 @@ +@extends('layout.main') + +@push('style') + +@endpush + +@section('content') +
+ + @php + $d = [ + 'total_petani' => 247, + 'total_survey' => 214, + 'survey_selesai' => 178, + 'survey_draft' => 36, + 'total_desa' => 8, + 'total_kecamatan' => 3, + 'new_month' => 12, + + 'enumerators' => [ + ['name'=>'Enumerator Ngada 1','done'=>72,'target'=>80,'color'=>'#28a745','bg'=>'rgba(40,167,69,.15)','tx'=>'#28a745'], + ['name'=>'Enumerator Ngada 2','done'=>58,'target'=>80,'color'=>'#007bff','bg'=>'rgba(0,123,255,.15)','tx'=>'#007bff'], + ['name'=>'Enumerator Ngada 3','done'=>48,'target'=>80,'color'=>'#fd7e14','bg'=>'rgba(253,126,20,.15)','tx'=>'#fd7e14'], + ['name'=>'Enumerator Ngada 4','done'=>36,'target'=>80,'color'=>'#dc3545','bg'=>'rgba(220,53,69,.15)','tx'=>'#dc3545'], + ], + + 'recent' => [ + ['code'=>'TKD-2026-0178','name'=>'Markus Bela', 'init'=>'MB','desa'=>'Wangka', 'date'=>'24 Jun 2026','pct'=>100,'status'=>'completed', 'bg'=>'rgba(40,167,69,.15)','tx'=>'#28a745'], + ['code'=>'TKD-2026-0177','name'=>'Theresia Nuka','init'=>'TN','desa'=>'Langa', 'date'=>'23 Jun 2026','pct'=>67, 'status'=>'in_progress','bg'=>'rgba(0,123,255,.15)','tx'=>'#007bff'], + ['code'=>'TKD-2026-0176','name'=>'Yosef Meo', 'init'=>'YM','desa'=>'Bobo', 'date'=>'22 Jun 2026','pct'=>100,'status'=>'completed', 'bg'=>'rgba(40,167,69,.15)','tx'=>'#28a745'], + ['code'=>'TKD-2026-0175','name'=>'Maria Seda', 'init'=>'MS','desa'=>'Tana Wolo','date'=>'21 Jun 2026','pct'=>22, 'status'=>'draft', 'bg'=>'rgba(253,126,20,.15)','tx'=>'#fd7e14'], + ['code'=>'TKD-2026-0174','name'=>'Rafael Bolo', 'init'=>'RB','desa'=>'Wangka', 'date'=>'20 Jun 2026','pct'=>11, 'status'=>'draft', 'bg'=>'rgba(220,53,69,.15)','tx'=>'#dc3545'], + ], + + 'komoditas' => [ + ['label'=>'Kopi', 'total'=>148,'pct'=>60,'color'=>'#28a745','arc'=>174], + ['label'=>'Kakao', 'total'=>82, 'pct'=>33,'color'=>'#007bff','arc'=>96], + ['label'=>'Vanili','total'=>33, 'pct'=>13,'color'=>'#fd7e14','arc'=>38], + ['label'=>'Kemiri','total'=>22, 'pct'=>9, 'color'=>'#6f42c1','arc'=>26], + ], + + 'kecamatan' => [ + ['name'=>'Bajawa','total'=>89,'pct'=>78,'color'=>'#28a745'], + ['name'=>'Soa', 'total'=>68,'pct'=>59,'color'=>'#007bff'], + ['name'=>'Golewa','total'=>57,'pct'=>50,'color'=>'#fd7e14'], + ], + + 'pending' => [ + ['name'=>'Theresia Nuka','section'=>'D4-K3','pct'=>67,'bg'=>'rgba(0,123,255,.15)','tx'=>'#007bff'], + ['name'=>'Maria Seda', 'section'=>'D2-K2','pct'=>22,'bg'=>'rgba(253,126,20,.15)','tx'=>'#fd7e14'], + ['name'=>'Rafael Bolo', 'section'=>'D2-K1','pct'=>11,'bg'=>'rgba(220,53,69,.15)', 'tx'=>'#dc3545'], + ['name'=>'Antonius Wea', 'section'=>'D2-K1','pct'=>0, 'bg'=>'rgba(220,53,69,.15)', 'tx'=>'#dc3545'], + ], + 'pending_more' => 32, + ]; + $C = 289; // circumference SVG r=46 + $donutOff = 0; + @endphp + + +
+
+
+
+
+
+ +
+ +{{ $d['new_month'] }} bulan ini +
+

Total Petani

+

{{ number_format($d['total_petani']) }}

+ {{ $d['total_desa'] }} desa · {{ $d['total_kecamatan'] }} kecamatan +
+
+
+
+
+
+
+
+ +
+ {{ $d['total_survey'] }} terdaftar +
+

Total Survey

+

{{ number_format($d['total_survey']) }}

+ dari {{ $d['total_petani'] }} petani +
+
+
+
+
+
+
+
+ +
+ + {{ round($d['survey_selesai'] / $d['total_survey'] * 100) }}% + +
+

Survey Selesai

+

{{ number_format($d['survey_selesai']) }}

+ siap untuk analisis +
+
+
+
+
+
+
+
+ +
+ + {{ round($d['survey_draft'] / $d['total_survey'] * 100) }}% + +
+

Survey Draft

+

{{ number_format($d['survey_draft']) }}

+ belum selesai diisi +
+
+
+
+ + +
+
+
+
+
+ Progres per Enumerator +
+ + {{ now()->format('M Y') }} + +
+
+ @foreach($d['enumerators'] as $e) + @php $pct = round($e['done'] / $e['target'] * 100); @endphp +
+
+ {{ strtoupper(substr($e['name'], 0, 2)) }} +
+
+
+ {{ $e['name'] }} + {{ $e['done'] }} / {{ $e['target'] }} survey +
+
+
+
+
+ {{ $pct }}% +
+
+
+ @endforeach +
+
+ + {{-- Survey Terbaru --}} +
+
+
+ Survey terbaru +
+ + Lihat semua + +
+
+ + + + + + + + + + + + + @foreach($d['recent'] as $s) + @php + $bc = match(true) { + $s['pct'] === 100 => '#28a745', + $s['pct'] >= 50 => '#007bff', + $s['pct'] >= 20 => '#fd7e14', + default => '#dc3545', + }; + @endphp + + + + + + + + + @endforeach + +
KodePetaniDesaTanggalProgresStatus
+ {{ $s['code'] }} + +
+
+ {{ $s['init'] }} +
+ {{ $s['name'] }} +
+
{{ $s['desa'] }}{{ $s['date'] }} +
+
+
+
+ + {{ $s['pct'] }}% + +
+
+ @if($s['status'] === 'completed') + Selesai + @elseif($s['status'] === 'in_progress') + Sedang diisi + @else + Draft + @endif +
+
+
+ +
+ +
+
+
+
+ Distribusi komoditas +
+
+
+
+ + + @foreach($d['komoditas'] as $k) + + @php $donutOff += $k['arc']; @endphp + @endforeach + + {{ $d['total_petani'] }} + + petani + +
+ @foreach($d['komoditas'] as $k) +
+
+ {{ $k['label'] }} + + {{ $k['total'] }} + {{ $k['pct'] }}% + +
+ @endforeach +
+
+
+
+
+ Per kecamatan +
+
+
+ @foreach($d['kecamatan'] as $kec) +
+
{{ $kec['name'] }}
+
+
+
+
{{ $kec['total'] }} survey
+
+ @endforeach +
+

+ Ngada, Nusa Tenggara Timur · {{ now()->year }} +

+
+
+ +
+
+
+ Draft tertunda +
+ + Lihat semua + +
+
+ @foreach($d['pending'] as $p) +
+ {{ $p['name'] }} + + {{ $p['section'] }} · {{ $p['pct'] }}% + +
+ @endforeach +
+
+ + {{ $d['pending_more'] }} lainnya + + Lihat semua → + +
+
+
+ +
+
+
+@endsection diff --git a/resources/views/layout/sidebar.blade.php b/resources/views/layout/sidebar.blade.php index e31ecce..d631add 100644 --- a/resources/views/layout/sidebar.blade.php +++ b/resources/views/layout/sidebar.blade.php @@ -1,6 +1,6 @@