Update Dasboard utama dan Survey

This commit is contained in:
2026-06-26 14:15:56 +07:00
parent 871b015ce2
commit 1517dd38cf
5 changed files with 730 additions and 30 deletions
@@ -4,6 +4,12 @@ namespace App\Http\Controllers\Web\Dashboard;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Illuminate\Http\Request; 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; use Illuminate\Support\Facades\Gate;
class SummaryController extends Controller class SummaryController extends Controller
@@ -16,4 +22,91 @@ class SummaryController extends Controller
$title = 'Summary Dashboard'; $title = 'Summary Dashboard';
return view('dashboard.summary', compact('title')); 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
]);
}
} }
@@ -0,0 +1,408 @@
@extends('layout.main')
@push('style')
<style>
.tk-stat {
border-left: 4px solid transparent;
transition: transform .2s ease;
}
.tk-stat:hover { transform: translateX(4px); }
.tk-stat.green { border-left-color: #28a745; }
.tk-stat.blue { border-left-color: #007bff; }
.tk-stat.amber { border-left-color: #fd7e14; }
.tk-stat-lbl {
font-size: 10px; text-transform: uppercase;
letter-spacing: .7px; font-weight: 600;
}
.tk-stat-val { font-size: 20px; font-weight: 800; line-height: 1; }
.tk-stat-top { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 10px; }
/* Progress bar */
.tk-pb { display: flex; align-items: center; gap: 6px; }
.tk-pbt {
flex: 1; height: 6px;
background: rgba(128,128,128,.15);
border-radius: 3px; overflow: hidden;
}
.tk-pbf { height: 100%; border-radius: 3px; }
.tk-bar { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.tk-bar-lbl { width: 72px; font-size: 11px; text-align: right; flex-shrink: 0; }
.tk-bar-trk {
flex: 1; height: 7px;
background: rgba(128,128,128,.15);
border-radius: 4px; overflow: hidden;
}
.tk-bar-fil { height: 100%; border-radius: 4px; }
.tk-bar-val { font-size: 11px; min-width: 54px; }
.tk-erow {
display: flex; align-items: center; gap: 10px;
padding: 9px 0;
border-bottom: 1px solid rgba(128,128,128,.1);
}
.tk-erow:last-child { border-bottom: none; }
.tk-av {
display: flex; align-items: center; justify-content: center;
font-size: 10px; font-weight: 700; flex-shrink: 0;
}
.tk-code {
font-size: 10px; padding: 2px 7px; border-radius: 5px;
font-family: monospace;
background: rgba(128,128,128,.12);
border: 1px solid rgba(128,128,128,.2);
white-space: nowrap;
}
/* Donut legend */
.tk-leg { display: flex; align-items: center; gap: 7px; margin-bottom: 7px; font-size: 12px; }
.tk-leg-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.tk-leg-val { margin-left: auto; font-weight: 700; font-size: 12px; }
/* Pending row */
.tk-pend { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; font-size: 12px; }
.tk-pend:last-child { margin-bottom: 0; }
.tk-chip { border-radius: 6px; padding: 2px 7px; font-size: 10px; font-weight: 700; }
.tk-divider { height: 1px; background: rgba(128,128,128,.1); margin: 10px 0; }
/* SVG donut text ikut warna teks tema */
.tk-donut-num { fill: var(--bs-body-color); font-size: 15px; font-weight: 800; }
.tk-donut-sub { fill: var(--bs-secondary-color, #6c757d); font-size: 9px; }
</style>
@endpush
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@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
<div class="row g-3 mb-4">
<div class="col-sm-6 col-xl-3">
<div class="card tk-stat green h-100">
<div class="card-body">
<div class="tk-stat-top">
<div class="avatar bg-label-success rounded p-2">
<i class="ti tabler-users fs-3"></i>
</div>
<span class="badge bg-label-success text-success">+{{ $d['new_month'] }} bulan ini</span>
</div>
<p class="tk-stat-lbl text-muted mb-1">Total Petani</p>
<h3 class="tk-stat-val mb-1">{{ number_format($d['total_petani']) }}</h3>
<small class="text-muted">{{ $d['total_desa'] }} desa &middot; {{ $d['total_kecamatan'] }} kecamatan</small>
</div>
</div>
</div>
<div class="col-sm-6 col-xl-3">
<div class="card tk-stat blue h-100">
<div class="card-body">
<div class="tk-stat-top">
<div class="avatar bg-label-primary rounded p-2">
<i class="ti tabler-clipboard-list fs-3"></i>
</div>
<span class="badge bg-label-primary text-primary">{{ $d['total_survey'] }} terdaftar</span>
</div>
<p class="tk-stat-lbl text-muted mb-1">Total Survey</p>
<h3 class="tk-stat-val mb-1">{{ number_format($d['total_survey']) }}</h3>
<small class="text-muted">dari {{ $d['total_petani'] }} petani</small>
</div>
</div>
</div>
<div class="col-sm-6 col-xl-3">
<div class="card tk-stat green h-100">
<div class="card-body">
<div class="tk-stat-top">
<div class="avatar bg-label-success rounded p-2">
<i class="ti tabler-circle-check fs-3"></i>
</div>
<span class="badge bg-label-success text-success">
{{ round($d['survey_selesai'] / $d['total_survey'] * 100) }}%
</span>
</div>
<p class="tk-stat-lbl text-muted mb-1">Survey Selesai</p>
<h3 class="tk-stat-val mb-1">{{ number_format($d['survey_selesai']) }}</h3>
<small class="text-muted">siap untuk analisis</small>
</div>
</div>
</div>
<div class="col-sm-6 col-xl-3">
<div class="card tk-stat amber h-100">
<div class="card-body">
<div class="tk-stat-top">
<div class="avatar bg-label-warning rounded p-2">
<i class="ti tabler-pencil fs-3"></i>
</div>
<span class="badge bg-label-warning text-warning">
{{ round($d['survey_draft'] / $d['total_survey'] * 100) }}%
</span>
</div>
<p class="tk-stat-lbl text-muted mb-1">Survey Draft</p>
<h3 class="tk-stat-val mb-1">{{ number_format($d['survey_draft']) }}</h3>
<small class="text-muted">belum selesai diisi</small>
</div>
</div>
</div>
</div>
<div class="row g-3">
<div class="col-xl-8">
<div class="card mb-3">
<div class="card-header d-flex justify-content-between align-items-center">
<h6 class="mb-0 fw-bold">
<i class="ti tabler-chart-bar me-2 text-success"></i>Progres per Enumerator
</h6>
<span class="badge bg-label-secondary text-secondary">
{{ now()->format('M Y') }}
</span>
</div>
<div class="card-body">
@foreach($d['enumerators'] as $e)
@php $pct = round($e['done'] / $e['target'] * 100); @endphp
<div class="tk-erow">
<div class="tk-av rounded"
style="width:36px;height:36px;background:{{ $e['bg'] }};color:{{ $e['tx'] }}">
{{ strtoupper(substr($e['name'], 0, 2)) }}
</div>
<div class="flex-grow-1">
<div class="d-flex justify-content-between mb-1">
<span class="fw-semibold" style="font-size:13px">{{ $e['name'] }}</span>
<small class="text-muted">{{ $e['done'] }} / {{ $e['target'] }} survey</small>
</div>
<div class="tk-pb">
<div class="tk-pbt">
<div class="tk-pbf" style="width:{{ $pct }}%;background:{{ $e['color'] }}"></div>
</div>
<small class="text-muted" style="min-width:30px;text-align:right">{{ $pct }}%</small>
</div>
</div>
</div>
@endforeach
</div>
</div>
{{-- Survey Terbaru --}}
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h6 class="mb-0 fw-bold">
<i class="ti tabler-clock me-2 text-primary"></i>Survey terbaru
</h6>
<a href="{{ route('survey.petani.index') }}" class="btn btn-sm btn-outline-success">
Lihat semua
</a>
</div>
<div class="table-responsive">
<table class="table table-hover mb-0" style="font-size:12.5px">
<thead class="table-light">
<tr>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase">Kode</th>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase">Petani</th>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase">Desa</th>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase">Tanggal</th>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase">Progres</th>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase">Status</th>
</tr>
</thead>
<tbody>
@foreach($d['recent'] as $s)
@php
$bc = match(true) {
$s['pct'] === 100 => '#28a745',
$s['pct'] >= 50 => '#007bff',
$s['pct'] >= 20 => '#fd7e14',
default => '#dc3545',
};
@endphp
<tr>
<td>
<span class="tk-code">{{ $s['code'] }}</span>
</td>
<td>
<div class="d-flex align-items-center gap-2">
<div class="tk-av rounded"
style="width:28px;height:28px;background:{{ $s['bg'] }};color:{{ $s['tx'] }}">
{{ $s['init'] }}
</div>
<span class="fw-semibold">{{ $s['name'] }}</span>
</div>
</td>
<td class="text-muted" style="font-size:12px">{{ $s['desa'] }}</td>
<td class="text-muted" style="font-size:11px">{{ $s['date'] }}</td>
<td style="min-width:110px">
<div class="tk-pb">
<div class="tk-pbt">
<div class="tk-pbf" style="width:{{ $s['pct'] }}%;background:{{ $bc }}"></div>
</div>
<small class="text-muted" style="min-width:28px;text-align:right">
{{ $s['pct'] }}%
</small>
</div>
</td>
<td>
@if($s['status'] === 'completed')
<span class="badge bg-label-success text-success">Selesai</span>
@elseif($s['status'] === 'in_progress')
<span class="badge bg-label-primary text-primary">Sedang diisi</span>
@else
<span class="badge bg-label-warning text-warning">Draft</span>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
<div class="col-xl-4">
<div class="card mb-3">
<div class="card-header">
<h6 class="mb-0 fw-bold">
<i class="ti tabler-plant me-2 text-success"></i>Distribusi komoditas
</h6>
</div>
<div class="card-body">
<div class="d-flex justify-content-center py-2">
<svg width="120" height="120" viewBox="0 0 120 120"
role="img" aria-label="Distribusi komoditas petani">
<circle cx="60" cy="60" r="46" fill="none"
stroke="rgba(128,128,128,.15)" stroke-width="16"/>
@foreach($d['komoditas'] as $k)
<circle cx="60" cy="60" r="46" fill="none"
stroke="{{ $k['color'] }}" stroke-width="16"
stroke-dasharray="{{ $k['arc'] }} {{ $C - $k['arc'] }}"
stroke-dashoffset="{{ -$donutOff }}"
transform="rotate(-90 60 60)"/>
@php $donutOff += $k['arc']; @endphp
@endforeach
<text x="60" y="56" text-anchor="middle"
class="tk-donut-num" font-size="15" font-weight="800" fill="currentColor">
{{ $d['total_petani'] }}
</text>
<text x="60" y="70" text-anchor="middle"
font-size="9" fill="currentColor" opacity=".5">petani</text>
</svg>
</div>
@foreach($d['komoditas'] as $k)
<div class="tk-leg">
<div class="tk-leg-dot" style="background:{{ $k['color'] }}"></div>
<span class="text-muted">{{ $k['label'] }}</span>
<span class="tk-leg-val">
{{ $k['total'] }}
<span class="text-muted fw-normal" style="font-size:10px">{{ $k['pct'] }}%</span>
</span>
</div>
@endforeach
</div>
</div>
<div class="card mb-3">
<div class="card-header">
<h6 class="mb-0 fw-bold">
<i class="ti tabler-map-pin me-2 text-primary"></i>Per kecamatan
</h6>
</div>
<div class="card-body">
@foreach($d['kecamatan'] as $kec)
<div class="tk-bar">
<div class="tk-bar-lbl text-muted">{{ $kec['name'] }}</div>
<div class="tk-bar-trk">
<div class="tk-bar-fil" style="width:{{ $kec['pct'] }}%;background:{{ $kec['color'] }}"></div>
</div>
<div class="tk-bar-val text-muted">{{ $kec['total'] }} survey</div>
</div>
@endforeach
<div class="tk-divider"></div>
<p class="text-center text-muted mb-0" style="font-size:10px">
Ngada, Nusa Tenggara Timur &middot; {{ now()->year }}
</p>
</div>
</div>
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h6 class="mb-0 fw-bold">
<i class="ti tabler-clock-pause me-2 text-warning"></i>Draft tertunda
</h6>
<a href="{{ route('survey.petani.index', ['status' => 'draft']) }}"
class="text-success fw-semibold" style="font-size:12px;text-decoration:none">
Lihat semua
</a>
</div>
<div class="card-body">
@foreach($d['pending'] as $p)
<div class="tk-pend">
<span class="text-muted">{{ $p['name'] }}</span>
<span class="tk-chip" style="background:{{ $p['bg'] }};color:{{ $p['tx'] }}">
{{ $p['section'] }} &middot; {{ $p['pct'] }}%
</span>
</div>
@endforeach
<div class="tk-divider"></div>
<div class="d-flex justify-content-between align-items-center">
<small class="text-muted">+ {{ $d['pending_more'] }} lainnya</small>
<a href="{{ route('survey.petani.index', ['status' => 'draft']) }}"
class="text-success fw-semibold" style="font-size:11px;text-decoration:none">
Lihat semua →
</a>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
+8 -21
View File
@@ -1,6 +1,6 @@
<aside id="layout-menu" class="layout-menu menu-vertical menu"> <aside id="layout-menu" class="layout-menu menu-vertical menu">
<div class="app-brand demo "> <div class="app-brand demo ">
<a href="{{ route('dashboard.summary') }}" class="app-brand-link"> <a href="{{ route('dashboard.produktivitas') }}" class="app-brand-link">
<span class="app-brand-logo demo"> <span class="app-brand-logo demo">
<span> <span>
<svg width="32" height="24" viewBox="0 0 32 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="32" height="24" viewBox="0 0 32 24" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -54,32 +54,19 @@
<a href="javascript:void(0);" class="menu-link menu-toggle"> <a href="javascript:void(0);" class="menu-link menu-toggle">
<i class="menu-icon icon-base ti tabler-smart-home"></i> <i class="menu-icon icon-base ti tabler-smart-home"></i>
<div data-i18n="Dashboards">Dashboards</div> <div data-i18n="Dashboards">Dashboards</div>
<div class="badge text-bg-danger rounded-pill ms-auto">5</div> <!-- <div class="badge text-bg-danger rounded-pill ms-auto">5</div> -->
</a> </a>
<ul class="menu-sub"> <ul class="menu-sub">
<li class="menu-item"> <li class="menu-item">
<a href="{{ route('dashboard.summary') }}" class="menu-link"> <a href="{{ route('dashboard.produktivitas') }}" class="menu-link">
<div data-i18n="Summary">Summary</div> <div data-i18n="Produktivitas">Produktivitas</div>
</a> </a>
</li> </li>
</ul>
<ul class="menu-sub">
<li class="menu-item"> <li class="menu-item">
<a href="{{ route('dashboard.resiliensi') }}" class="menu-link"> <a href="{{ route('dashboard.survey') }}" class="menu-link">
<div data-i18n="Reseliensi">Reseliensi</div> <div data-i18n="Survey">Survey</div>
</a>
</li>
<li class="menu-item">
<a href="{{ route('dashboard.hilirisasi') }}" class="menu-link">
<div data-i18n="Hilirisasi">Hilirisasi</div>
</a>
</li>
<li class="menu-item">
<a href="{{ route('dashboard.konektivitas') }}" class="menu-link">
<div data-i18n="Konektivitas">Konektivitas</div>
</a>
</li>
<li class="menu-item">
<a href="{{ route('dashboard.akselerasi') }}" class="menu-link">
<div data-i18n="Akselerasi">Akselerasi</div>
</a> </a>
</li> </li>
</ul> </ul>
@@ -0,0 +1,202 @@
@extends('layout.main')
@push('style')
<style>
.tk-code {
background: rgba(128,128,128,.12);
border: 1px solid rgba(128,128,128,.2);
white-space: nowrap;
}
.tk-av {
display: flex; align-items: center; justify-content: center;
/* font-size: 12px; font-weight: 700; flex-shrink: 0; */
border-radius: 8px;
}
.tk-pb { display: flex; align-items: center; gap: 6px; }
.tk-pbt {
flex: 1; height: 6px;
background: rgba(128,128,128,.15);
border-radius: 3px; overflow: hidden; min-width: 60px;
}
.tk-pbf { height: 100%; border-radius: 3px; }
</style>
@endpush
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@php
$surveys = [
['code'=>'TKD-2026-0178','name'=>'Markus Bela', 'init'=>'MB','gender'=>'L','age'=>48,'desa'=>'Wangka', 'kec'=>'Bajawa', 'enum'=>'Enum. Ngada 1','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','gender'=>'P','age'=>42,'desa'=>'Langa', 'kec'=>'Bajawa', 'enum'=>'Enum. Ngada 2','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','gender'=>'L','age'=>53,'desa'=>'Bobo', 'kec'=>'Soa', 'enum'=>'Enum. Ngada 1','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','gender'=>'P','age'=>55,'desa'=>'Tana Wolo', 'kec'=>'Golewa', 'enum'=>'Enum. Ngada 3','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','gender'=>'L','age'=>38,'desa'=>'Wangka', 'kec'=>'Bajawa', 'enum'=>'Enum. Ngada 4','date'=>'20 Jun 2026','pct'=>11, 'status'=>'draft', 'bg'=>'rgba(220,53,69,.15)', 'tx'=>'#dc3545'],
['code'=>'TKD-2026-0173','name'=>'Antonius Wea', 'init'=>'AW','gender'=>'L','age'=>61,'desa'=>'Bobo', 'kec'=>'Soa', 'enum'=>'Enum. Ngada 3','date'=>'19 Jun 2026','pct'=>0, 'status'=>'draft', 'bg'=>'rgba(111,66,193,.15)','tx'=>'#6f42c1'],
['code'=>'TKD-2026-0172','name'=>'Floriana Keu', 'init'=>'FK','gender'=>'P','age'=>44,'desa'=>'Langa', 'kec'=>'Bajawa', 'enum'=>'Enum. Ngada 2','date'=>'18 Jun 2026','pct'=>100,'status'=>'completed', 'bg'=>'rgba(40,167,69,.15)', 'tx'=>'#28a745'],
['code'=>'TKD-2026-0171','name'=>'Dominikus Ngae','init'=>'DN','gender'=>'L','age'=>49,'desa'=>'Tana Wolo','kec'=>'Golewa', 'enum'=>'Enum. Ngada 1','date'=>'17 Jun 2026','pct'=>100,'status'=>'completed', 'bg'=>'rgba(40,167,69,.15)', 'tx'=>'#28a745'],
['code'=>'TKD-2026-0170','name'=>'Agustina Meo', 'init'=>'AM','gender'=>'P','age'=>37,'desa'=>'Bobo', 'kec'=>'Soa', 'enum'=>'Enum. Ngada 2','date'=>'16 Jun 2026','pct'=>45, 'status'=>'in_progress','bg'=>'rgba(0,123,255,.15)','tx'=>'#007bff'],
['code'=>'TKD-2026-0169','name'=>'Yohanes Lewa', 'init'=>'YL','gender'=>'L','age'=>57,'desa'=>'Wangka', 'kec'=>'Bajawa', 'enum'=>'Enum. Ngada 4','date'=>'15 Jun 2026','pct'=>100,'status'=>'completed', 'bg'=>'rgba(40,167,69,.15)', 'tx'=>'#28a745'],
];
$total = 214; $selesai = 178; $sdraft = 36;
@endphp
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h4 class="fw-bold mb-1">Daftar Survey</h4>
<p class="text-muted mb-0" style="font-size:13px">
{{ $total }} survey &middot;
<span class="text-success fw-semibold">{{ $selesai }} selesai</span> &middot;
<span class="text-warning fw-semibold">{{ $sdraft }} draft</span>
</p>
</div>
<a href="{{ route('survey.petani.create') }}" class="btn btn-success">
<i class="ti tabler-plus me-1"></i> Survey Baru
</a>
</div>
<div class="card mb-3">
<div class="card-body py-3">
<div class="row g-2 align-items-center">
<div class="col-md-4">
<div class="input-group input-group-sm">
<span class="input-group-text bg-transparent">
<i class="ti tabler-search"></i>
</span>
<input type="text" class="form-control"
placeholder="Cari nama petani / kode survey...">
</div>
</div>
<div class="col-md-2">
<select class="form-select form-select-sm">
<option>Semua Status</option>
<option>Selesai</option>
<option>Sedang diisi</option>
<option>Draft</option>
</select>
</div>
<div class="col-md-2">
<select class="form-select form-select-sm">
<option>Semua Kecamatan</option>
<option>Bajawa</option>
<option>Soa</option>
<option>Golewa</option>
</select>
</div>
<div class="col-md-2">
<select class="form-select form-select-sm">
<option>Semua Enumerator</option>
<option>Enumerator Ngada 1</option>
<option>Enumerator Ngada 2</option>
<option>Enumerator Ngada 3</option>
<option>Enumerator Ngada 4</option>
</select>
</div>
<div class="col-md-2">
<button class="btn btn-outline-secondary btn-sm w-100">
<i class="ti tabler-refresh me-1"></i> Reset
</button>
</div>
</div>
</div>
</div>
<div class="card">
<div class="table-responsive">
<table class="table table-hover mb-0" style="font-size:12.5px">
<thead class="table-light">
<tr>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase;width:120px">Kode</th>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase">Petani</th>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase;width:80px">Desa</th>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase;width:90px">Kecamatan</th>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase;width:115px">Enumerator</th>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase;width:92px">Tanggal</th>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase;width:120px">Progres</th>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase;width:98px">Status</th>
<th style="font-size:10px;letter-spacing:.7px;text-transform:uppercase;width:65px;text-align:center">Aksi</th>
</tr>
</thead>
<tbody>
@foreach($surveys as $s)
@php
$bc = match(true) {
$s['pct'] === 100 => '#28a745',
$s['pct'] >= 50 => '#007bff',
$s['pct'] >= 20 => '#fd7e14',
default => '#dc3545',
};
@endphp
<tr>
<td><span class="tk-code">{{ $s['code'] }}</span></td>
<td>
<div class="d-flex align-items-center gap-2">
<div class="tk-av"
style="width:28px;height:28px;background:{{ $s['bg'] }};color:{{ $s['tx'] }}">
{{ $s['init'] }}
</div>
<div>
<div class="fw-semibold" style="font-size:13px">{{ $s['name'] }}</div>
<div class="text-muted" style="font-size:10px">
{{ $s['gender'] }} &middot; {{ $s['age'] }} th
</div>
</div>
</div>
</td>
<td class="text-muted" style="font-size:12px">{{ $s['desa'] }}</td>
<td class="text-muted" style="font-size:12px">{{ $s['kec'] }}</td>
<td class="text-muted" style="font-size:11px">{{ $s['enum'] }}</td>
<td class="text-muted" style="font-size:11px">{{ $s['date'] }}</td>
<td>
<div class="tk-pb">
<div class="tk-pbt">
<div class="tk-pbf" style="width:{{ $s['pct'] }}%;background:{{ $bc }}"></div>
</div>
<small class="text-muted" style="min-width:28px;text-align:right">
{{ $s['pct'] }}%
</small>
</div>
</td>
<td>
@if($s['status'] === 'completed')
<span class="badge bg-label-success text-success">Selesai</span>
@elseif($s['status'] === 'in_progress')
<span class="badge bg-label-primary text-primary">Sedang diisi</span>
@else
<span class="badge bg-label-warning text-warning">Draft</span>
@endif
</td>
<td class="text-center">
@if($s['status'] === 'completed')
<a href="#" class="btn btn-sm btn-icon btn-outline-secondary" title="Detail">
<i class="ti tabler-eye"></i>
</a>
@else
<a href="#" class="btn btn-sm btn-icon btn-outline-primary" title="Lanjutkan isi">
<i class="ti tabler-edit"></i>
</a>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
{{-- Pagination --}}
<div class="card-footer d-flex justify-content-between align-items-center py-2">
<small class="text-muted">Menampilkan 1–10 dari {{ $total }} survey</small>
<nav>
<ul class="pagination pagination-sm mb-0">
<li class="page-item disabled"><a class="page-link" href="#">‹</a></li>
<li class="page-item active"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item disabled"><a class="page-link" href="#">...</a></li>
<li class="page-item"><a class="page-link" href="#">22</a></li>
<li class="page-item"><a class="page-link" href="#">›</a></li>
</ul>
</nav>
</div>
</div>
</div>
@endsection
+11 -1
View File
@@ -14,6 +14,16 @@ Route::view('/offline', 'offline')->name('offline');
Route::middleware('auth') Route::middleware('auth')
->group(function () { ->group(function () {
Route::get('/tekad', function () {
return view('dashboard.dashboard');
})->name('dashboard.survey');
Route::get('/survey/petani', function () {
return view('survey.petani.index');
})->name('survey.petani.index');
Route::get('/survey/petani/create', function () {
return view('survey.petani.create');
})->name('survey.petani.create');
// Home // Home
Route::get('/', [App\Http\Controllers\Web\Dashboard\SummaryController::class, 'produktivitas'])->name('dashboard.produktivitas'); Route::get('/', [App\Http\Controllers\Web\Dashboard\SummaryController::class, 'produktivitas'])->name('dashboard.produktivitas');
Route::get('/UserProfile', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'index'])->name('userProfile.index'); Route::get('/UserProfile', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'index'])->name('userProfile.index');
@@ -22,7 +32,7 @@ Route::middleware('auth')
Route::patch('/UserProfile/password', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'updatePassword'])->name('userProfile.password.update'); Route::patch('/UserProfile/password', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'updatePassword'])->name('userProfile.password.update');
Route::post('/UserProfile/logout-devices', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'logoutDevices'])->name('userProfile.logoutDevices'); Route::post('/UserProfile/logout-devices', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'logoutDevices'])->name('userProfile.logoutDevices');
Route::get('/', [App\Http\Controllers\Web\Dashboard\SummaryController::class, 'index'])->name('dashboard.summary'); // Route::get('/', [App\Http\Controllers\Web\Dashboard\SummaryController::class, 'index'])->name('dashboard.summary');
Route::get('/resiliensi', [App\Http\Controllers\Web\Dashboard\ResiliensiController::class, 'index'])->name('dashboard.resiliensi'); Route::get('/resiliensi', [App\Http\Controllers\Web\Dashboard\ResiliensiController::class, 'index'])->name('dashboard.resiliensi');
Route::get('/hilirisasi', [App\Http\Controllers\Web\Dashboard\HilirisasiController::class, 'index'])->name('dashboard.hilirisasi'); Route::get('/hilirisasi', [App\Http\Controllers\Web\Dashboard\HilirisasiController::class, 'index'])->name('dashboard.hilirisasi');
Route::get('/konektivitas', [App\Http\Controllers\Web\Dashboard\KonektivitasController::class, 'index'])->name('dashboard.konektivitas'); Route::get('/konektivitas', [App\Http\Controllers\Web\Dashboard\KonektivitasController::class, 'index'])->name('dashboard.konektivitas');