18 Commits
Author SHA1 Message Date
afriadirahman 16a0a3c56c Update Icon Demografi Dashboard 2026-08-07 11:33:08 +07:00
afriadirahman d4c6b64ba6 Update Sidebar Demografi Petani 2026-08-07 11:20:05 +07:00
afriadirahman b4089d72b3 Update Dashboard Demografi Petani 2026-08-07 11:17:53 +07:00
afriadirahman 01990ccec1 Merge branch 'main' of https://git.probindo.com/Probindo/database-pertani-web 2026-08-06 13:29:42 +07:00
irwan.l.cahyono 8aed88a31f dashboard indeks petani 2026-08-05 01:20:19 +07:00
irwan.l.cahyono 4aa0780802 dashboard profil petani komp 4 2026-08-03 13:08:01 +07:00
afriadirahman 4e41246382 Update Profile Petani Dashboard 2026-08-03 12:53:20 +07:00
irwan.l.cahyono c8d1994d3b dashboard profil petani 2026-07-30 15:23:34 +07:00
irwan.l.cahyono 24a8016710 petani booted skor 2026-07-29 16:52:51 +07:00
irwan.l.cahyono 20e1eee6ff skor petani domain komponen hitung 2026-07-29 16:27:33 +07:00
afriadirahman c0432cd5f8 Update Sidebar Filter Fasilitator 2026-07-29 16:12:31 +07:00
irwan.l.cahyono 0ce0936a80 skor petani update 2026-07-29 16:05:43 +07:00
Syaharani 502c932f21 Merge branch 'main' of https://git.probindo.com/Probindo/database-pertani-web 2026-07-28 16:54:37 +07:00
Syaharani e60a66eeb7 bumdes: profil & add pengurus bumdes 2026-07-28 16:54:27 +07:00
afriadirahman 4475cd0098 Update Logo Sidebar 2026-07-28 16:18:41 +07:00
afriadirahman 67c111a2b3 Update Logo Agromonev & Agropro 2026-07-28 16:10:47 +07:00
Syaharani 3bcaa3ea50 solve survey produktivitas 2026-07-27 10:14:36 +07:00
Syaharani bed9a6f620 solve 2026-07-23 18:26:24 +07:00
26 changed files with 3948 additions and 283 deletions
+46
View File
@@ -0,0 +1,46 @@
<?php
namespace App\Enums\Bumdes;
enum JabatanBumdes: string
{
case DIREKTUR = 'direktur';
case DIREKTUR_KETUA = 'direktur_ketua';
case SEKRETARIS = 'sekretaris';
case BENDAHARA = 'bendahara';
case KEPALA_UNIT_USAHA = 'kepala_unit_usaha';
case PENGAWAS = 'pengawas';
case PENASIHAT = 'penasihat';
case ANGGOTA = 'anggota';
case STAF_OPERASIONAL = 'staf_operasional';
case LAINNYA = 'lainnya';
public function label(): string
{
return match ($this) {
self::DIREKTUR => 'Direktur/Ketua',
self::DIREKTUR_KETUA => 'Direktur/Ketua',
self::SEKRETARIS => 'Sekretaris',
self::BENDAHARA => 'Bendahara',
self::KEPALA_UNIT_USAHA => 'Kepala Unit Usaha',
self::PENGAWAS => 'Pengawas',
self::PENASIHAT => 'Penasihat',
self::ANGGOTA => 'Anggota',
self::STAF_OPERASIONAL => 'Staf Operasional',
self::LAINNYA => 'Lainnya',
};
}
public static function options(): array
{
return collect([
self::DIREKTUR_KETUA,
self::SEKRETARIS,
self::BENDAHARA,
self::LAINNYA,
])->map(fn ($case) => [
'value' => $case->value,
'label' => $case->label(),
])->toArray();
}
}
@@ -0,0 +1,218 @@
<?php
namespace App\Http\Controllers\Web\Bumdes;
use App\Enums\Bumdes\JabatanBumdes;
use App\Enums\Pendidikan;
use App\Http\Controllers\Controller;
use App\Models\Bumdes\PengurusBumdes;
use App\Models\Wilayah\Provinsi;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
class PengurusBumdesController extends Controller
{
public function index(Request $request)
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$query = PengurusBumdes::with([
'desaKelurahan:id,nama,kecamatan_id',
'desaKelurahan.kecamatan:id,nama,kabupaten_kota_id',
'desaKelurahan.kecamatan.kabupatenKota:id,nama,provinsi_id',
'desaKelurahan.kecamatan.kabupatenKota.provinsi:id,nama',
'creator:id,name',
])
->orderBy('created_at', 'desc');
if ($request->search) {
$query->where(function ($query) use ($request) {
$query->where('nama', 'like', '%' . $request->search . '%')
->orWhere('jabatan', 'like', '%' . $request->search . '%')
->orWhere('jabatan_lainnya', 'like', '%' . $request->search . '%');
});
}
if (auth()->user()->role->value === 'fasilitator') {
$query->where('created_by', auth()->id());
}
$summaryQuery = clone $query;
$totalPengurus = (clone $summaryQuery)->count();
$totalLakiLaki = (clone $summaryQuery)->where('jenis_kelamin', true)->count();
$totalPerempuan = (clone $summaryQuery)->where('jenis_kelamin', false)->count();
$totalDesaKelurahan = (clone $summaryQuery)->distinct('desa_kelurahan_id')->count('desa_kelurahan_id');
$totalJabatan = (clone $summaryQuery)->distinct('jabatan')->count('jabatan');
$pengurus = $query->paginate($request->per_page ?? 10);
$userRole = auth()->user()->role->value;
$showEnumerator = in_array($userRole, ['super_admin', 'admin']);
return view('bumdes.profil.index', compact(
'pengurus',
'totalPengurus',
'totalLakiLaki',
'totalPerempuan',
'totalDesaKelurahan',
'totalJabatan',
'showEnumerator'
));
}
public function create()
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$provinsi = Provinsi::select('id', 'kode', 'nama')->orderBy('kode', 'asc')->get();
$jabatan = JabatanBumdes::options();
$pendidikan = Pendidikan::options();
return view('bumdes.profil.add', compact('provinsi', 'jabatan', 'pendidikan'));
}
public function store(Request $request)
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$validatedData = $this->validatedData($request);
$pengurus = PengurusBumdes::create([
...$this->formatData($validatedData),
'uid' => 'BMD-' . strtoupper(Str::random(10)),
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
return redirect()->route('bumdes.edit', $pengurus->id)->with('success', 'Data pengurus BUMDes berhasil ditambahkan.');
}
public function show(string $id)
{
return redirect()->route('bumdes.edit', $id);
}
public function edit(string $id)
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$pengurus = $this->pengurusQuery()->with([
'desaKelurahan.kecamatan.kabupatenKota.provinsi',
])->findOrFail($id);
$provinsi = Provinsi::select('id', 'kode', 'nama')->orderBy('kode', 'asc')->get();
$jabatan = JabatanBumdes::options();
$pendidikan = Pendidikan::options();
return view('bumdes.profil.edit', compact('pengurus', 'provinsi', 'jabatan', 'pendidikan'));
}
public function update(Request $request, string $id)
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$pengurus = $this->pengurusQuery()->findOrFail($id);
$validatedData = $this->validatedData($request);
$pengurus->update([
...$this->formatData($validatedData),
'updated_by' => auth()->id(),
]);
return redirect()->route('bumdes.edit', $pengurus->id)->with('success', 'Data pengurus BUMDes berhasil diupdate.');
}
public function destroy(string $id)
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$pengurus = $this->pengurusQuery()->findOrFail($id);
$pengurus->update(['deleted_by' => auth()->id()]);
$pengurus->delete();
return response()->json(['message' => 'Data pengurus BUMDes berhasil dihapus.']);
}
public function kelembagaanAktor(string $id)
{
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$pengurus = $this->pengurusQuery()->with([
'desaKelurahan.kecamatan.kabupatenKota.provinsi',
])->findOrFail($id);
return view('bumdes.kelembagaan-aktor.index', compact('pengurus'));
}
private function pengurusQuery()
{
$query = PengurusBumdes::query();
if (auth()->user()->role->value === 'fasilitator') {
$query->where('created_by', auth()->id());
}
return $query;
}
private function validatedData(Request $request): array
{
return $request->validate([
'nama' => ['required', 'string', 'max:255'],
'jenis_kelamin' => ['required', 'boolean'],
'tempat_lahir' => ['required', 'string', 'max:255'],
'tanggal_lahir' => ['required', 'date_format:d-m-Y'],
'pendidikan_terakhir' => ['required', Rule::enum(Pendidikan::class)],
'alamat' => ['required', 'string', 'max:500'],
'desa_kelurahan_id' => ['required', 'exists:master_desa_kelurahan,id'],
'nomor_telepon' => ['nullable', 'digits_between:11,13'],
'jabatan' => ['required', Rule::enum(JabatanBumdes::class)],
'jabatan_lainnya' => ['nullable', 'required_if:jabatan,' . JabatanBumdes::LAINNYA->value, 'string', 'max:255'],
'lama_menjabat_tahun' => ['required', 'integer', 'min:0', 'max:80'],
], [
'nama.required' => 'Nama harus diisi.',
'jenis_kelamin.required' => 'Jenis kelamin harus dipilih.',
'tempat_lahir.required' => 'Tempat lahir harus diisi.',
'tanggal_lahir.required' => 'Tanggal lahir harus diisi.',
'tanggal_lahir.date_format' => 'Tanggal lahir harus menggunakan format tanggal yang valid.',
'pendidikan_terakhir.required' => 'Pendidikan terakhir harus dipilih.',
'alamat.required' => 'Alamat harus diisi.',
'desa_kelurahan_id.required' => 'Desa kelurahan harus dipilih.',
'desa_kelurahan_id.exists' => 'Desa kelurahan tidak ditemukan.',
'nomor_telepon.digits_between' => 'Nomor telepon harus berupa angka 11 sampai 13 digit.',
'jabatan.required' => 'Jabatan/peran harus dipilih.',
'jabatan_lainnya.required_if' => 'Jabatan lainnya harus diisi.',
'lama_menjabat_tahun.required' => 'Lama menjabat harus diisi.',
'lama_menjabat_tahun.integer' => 'Lama menjabat harus berupa angka tahun.',
]);
}
private function formatData(array $data): array
{
$data['tanggal_lahir'] = Carbon::createFromFormat('d-m-Y', $data['tanggal_lahir'])->format('Y-m-d');
$data['tanggal_mulai_menjabat'] = Carbon::now()
->subYears((int) $data['lama_menjabat_tahun'])
->format('Y-m-d');
if (($data['jabatan'] ?? null) !== JabatanBumdes::LAINNYA->value) {
$data['jabatan_lainnya'] = null;
}
return $data;
}
}
@@ -0,0 +1,123 @@
<?php
namespace App\Http\Controllers\Web\Dashboard;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use App\Models\Pertanian\Petani;
use App\Models\Pertanian\Komoditas;
use App\Models\Pertanian\Lahan;
use App\Models\Pertanian\PendapatanKomoditas;
class DemografiPetaniController extends Controller
{
public function index(Request $request)
{
$totalPetani = Petani::count();
$petaniLakilaki = Petani::where('jenis_kelamin', 1)->count();
$petaniPerempuan = Petani::where('jenis_kelamin', 0)->count();
$totalKomoditas = Petani::whereNotNull('komoditas_id')
->distinct()
->count('komoditas_id');
$totalLuasLahan = Lahan::has('petani')
->sum('luas_lahan');
$ratarataLuasLahan = Lahan::has('petani')
->avg('luas_lahan');
$umurKurang30 = Petani::whereNotNull('tanggal_lahir')->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) < 30")->count();
$umur30sampai39 = Petani::whereNotNull('tanggal_lahir')->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 30 AND 39")->count();
$umur40sampai49 = Petani::whereNotNull('tanggal_lahir')->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 40 AND 49")->count();
$umur50sampai59 = Petani::whereNotNull('tanggal_lahir')->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 50 AND 59")->count();
$umur60keatas = Petani::whereNotNull('tanggal_lahir')->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) >= 60")->count();
$pendidikanCounts = Petani::whereNotNull('pendidikan_terakhir')
->select('pendidikan_terakhir', DB::raw('COUNT(*) as total'))
->groupBy('pendidikan_terakhir')
->pluck('total', 'pendidikan_terakhir');
$pendidikan = [
'tidak_sekolah' => (int) ($pendidikanCounts['01_tidak_sekolah'] ?? 0),
'sd' => (int) ($pendidikanCounts['02_sd'] ?? 0),
'smp' => (int) ($pendidikanCounts['03_smp'] ?? 0),
'sma' => (int) ($pendidikanCounts['04_sma'] ?? 0),
'diploma' => (int) ($pendidikanCounts['05_diploma'] ?? 0),
's1_keatas' =>
(int) ($pendidikanCounts['06_sarjana'] ?? 0) +
(int) ($pendidikanCounts['07_magister'] ?? 0),
];
$komoditasUtama = Komoditas::query()
->whereHas('petani')
->withCount('petani')
->orderByDesc('petani_count')
->get(['id', 'nama']);
$luasLahanPerPetani = Lahan::has('petani')
->select('petani_id')
->selectRaw('SUM(luas_lahan) as total_luas')
->groupBy('petani_id')
->get();
$luasLahan = [
'kurang_05' => $luasLahanPerPetani->filter(fn ($item) => $item->total_luas < 5000)->count(),
'05_1' => $luasLahanPerPetani->filter(fn ($item) => $item->total_luas >= 5000 && $item->total_luas <= 10000)->count(),
'1_2' => $luasLahanPerPetani->filter(fn ($item) => $item->total_luas > 10000 && $item->total_luas <= 20000)->count(),
'lebih_2' => $luasLahanPerPetani->filter(fn ($item) => $item->total_luas > 20000)->count(),
];
$pendapatanPerPetani = PendapatanKomoditas::with('sosialEkonomi.petani')->get()
->filter(fn ($item) => $item->sosialEkonomi?->petani)
->groupBy(fn ($item) => $item->sosialEkonomi->petani_id)
->map(fn ($items) => $items->sum('pendapatan'));
$penghasilan = [
'kurang_1' => $pendapatanPerPetani->filter(fn ($value) => $value < 1000000)->count(),
'1_3' => $pendapatanPerPetani->filter(fn ($value) => $value >= 1000000 && $value <= 3000000)->count(),
'3_5' => $pendapatanPerPetani->filter(fn ($value) => $value > 3000000 && $value <= 5000000)->count(),
'5_10' => $pendapatanPerPetani->filter(fn ($value) => $value > 5000000 && $value <= 10000000)->count(),
'lebih_10' => $pendapatanPerPetani->filter(fn ($value) => $value > 10000000)->count(),
];
$data = [
'total_petani' => $totalPetani,
'petani_lakilaki' => $petaniLakilaki,
'petani_perempuan' => $petaniPerempuan,
'total_komoditas' => $totalKomoditas,
'total_luas_lahan' => $totalLuasLahan,
'ratarata_luas_lahan' => $ratarataLuasLahan,
'kelompok_umur' => [
'kurang_30' => $umurKurang30,
'30_39' => $umur30sampai39,
'40_49' => $umur40sampai49,
'50_59' => $umur50sampai59,
'60_keatas' => $umur60keatas,
],
'pendidikan' => $pendidikan,
'komoditas_utama' => [
'labels' => $komoditasUtama
->pluck('nama')
->values(),
'series' => $komoditasUtama
->pluck('petani_count')
->map(fn ($value) => (int) $value)
->values(),
],
'luas_lahan' => $luasLahan,
'penghasilan' => $penghasilan,
];
$daftarPetani = Petani::with([
'komoditas'
])
->withSum('lahans as total_luas_lahan', 'luas_lahan')
->orderBy('id')
->paginate(10);
// dd($daftarPetani);
return view('dashboard.demografi-petani', compact('data', 'daftarPetani'));
}
}
@@ -0,0 +1,125 @@
<?php
namespace App\Http\Controllers\Web\Dashboard;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\DB;
use App\Models\Pertanian\Petani;
use App\Models\Pertanian\Komoditas;
use App\Models\Pertanian\Lahan;
use App\Models\Pertanian\Tanaman;
use App\Models\Pertanian\SkorPetani;
class IndeksPetaniController extends Controller
{
public function index()
{
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403);
}
$title = 'Dashboard Profil Petani';
$komoditas = Komoditas::where('is_utama', true)->get();
$petani = Petani::pluck('id');
$lahan = Lahan::whereIn('petani_id', $petani)->get();
$case = "
CASE
WHEN skor_kesiapan_adopsi >= 4.0 THEN 'Penggerak'
WHEN skor_kesiapan_adopsi >= 3.0 THEN 'Perintis'
WHEN skor_kesiapan_adopsi >= 2.0 THEN 'Pemerhati'
WHEN skor_kesiapan_adopsi >= 1.0 THEN 'Pemula'
ELSE 'Belum Lengkap'
END
";
$countPetani = Petani::whereIn('id', $petani)->count();
$countKomoditas = Petani::whereIn('id', $petani)->whereIn('komoditas_id', $komoditas->pluck('id'))->distinct()->count('komoditas_id');
$sumLahan = Lahan::whereIn('petani_id', $petani)->whereIn('komoditas_id', $komoditas->pluck('id'))->sum('luas_lahan');
$avgLahan = Lahan::whereIn('petani_id', $petani)->whereIn('komoditas_id', $komoditas->pluck('id'))->avg('luas_lahan');
$avgSkor = SkorPetani::query()
->join('petani', 'petani_skor.petani_id', '=', 'petani.id')
->whereIn('petani_id', $petani)
->whereIn('petani.komoditas_id', $komoditas->pluck('id'))
->avg('skor_kesiapan_adopsi');
if ($avgSkor >= 4.0) {
$avgSegmen = 'Penggerak';
} elseif ($avgSkor >= 3.0) {
$avgSegmen = 'Perintis';
} elseif ($avgSkor >= 2.0) {
$avgSegmen = 'Pemerhati';
} elseif ($avgSkor >= 1.0) {
$avgSegmen = 'Pemula';
} else {
$avgSegmen = 'Belum Lengkap';
}
$countDesa = Petani::whereIn('id', $petani)->whereIn('komoditas_id', $komoditas->pluck('id'))->distinct()->count('desa_kelurahan_id');
$countKecamatan = Petani::whereIn('petani.id', $petani)
->join('master_desa_kelurahan', 'petani.desa_kelurahan_id', '=', 'master_desa_kelurahan.id')
->join('master_kecamatan', 'master_desa_kelurahan.kecamatan_id', '=', 'master_kecamatan.id')
->whereIn('komoditas_id', $komoditas->pluck('id'))->distinct()->count('master_kecamatan.id');
$countSegmentasi = SkorPetani::selectRaw("$case AS segmen, COUNT(*) AS total")
->whereIn('petani_id', $petani)
->groupByRaw($case)
->get();
$countSegmentasiByKomoditas = SkorPetani::query()
->join('petani', 'petani_skor.petani_id', '=', 'petani.id')
->selectRaw("
petani.komoditas_id,
$case AS segmen,
COUNT(petani.id) AS total
")
->whereIn('petani_skor.petani_id', $petani)
->groupBy('petani.komoditas_id')
->groupByRaw($case)
->get();
$avgDimensi = SkorPetani::query()
->join('petani', 'petani_skor.petani_id', '=', 'petani.id')
->whereIn('petani_id', $petani)
->whereIn('petani.komoditas_id', $komoditas->pluck('id'))
->selectRaw("
avg(skor_d2_sistem_praktik_budidaya) as skor_d2_sistem_praktik_budidaya,
avg(skor_d4_sosial_ekonomi) as skor_d4_sosial_ekonomi,
avg(skor_d6_rantai_nilai_akses_pasar) as skor_d6_rantai_nilai_akses_pasar")
->first();
$avgKomponen = SkorPetani::query()
->join('petani', 'petani_skor.petani_id', '=', 'petani.id')
->whereIn('petani_id', $petani)
->whereIn('petani.komoditas_id', $komoditas->pluck('id'))
->selectRaw("avg(skor_komp_1_d4_k3_motivasi_kapasitas_adopsi) as skor_komp_1_d4_k3_motivasi_kapasitas_adopsi,
avg(skor_komp_2_d4_k2_ekonomi_rumah_tangga) as skor_komp_2_d4_k2_ekonomi_rumah_tangga,
avg(skor_komp_3_d2_praktik_budidaya_gap) as skor_komp_3_d2_praktik_budidaya_gap,
avg(skor_komp_4_d4_k4_keterlibatan_kelembagaan) as skor_komp_4_d4_k4_keterlibatan_kelembagaan,
avg(skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan) as skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan,
avg(skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar) as skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar")
->first();
return view('dashboard.indeks-petani', compact(
'komoditas',
'countPetani',
'countKomoditas',
'sumLahan',
'avgLahan',
'avgSkor',
'avgSegmen',
'countDesa',
'countKecamatan',
'countSegmentasi',
'countSegmentasiByKomoditas',
'avgDimensi',
'avgKomponen'
));
}
}
@@ -75,7 +75,6 @@ class ProfilPetaniController extends Controller
->groupByRaw($case)
->get();
$skorAverage = SkorPetani::query()
->join('petani', 'petani_skor.petani_id', '=', 'petani.id')
->whereIn('petani_id', $petani)
@@ -111,7 +110,7 @@ class ProfilPetaniController extends Controller
avg(skor_komp_2_d4_k2_ekonomi_rumah_tangga) as skor_komp_2_d4_k2_ekonomi_rumah_tangga,
avg(skor_komp_3_d2_praktik_budidaya_gap) as skor_komp_3_d2_praktik_budidaya_gap,
avg(skor_komp_4_d4_k4_keterlibatan_kelembagaan) as skor_komp_4_d4_k4_keterlibatan_kelembagaan,
avg(skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan) as skor_komp_5_d4_k5_k6_akses_kebebasan_keuanga,
avg(skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan) as skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan,
avg(skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar) as skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar")
->first();
@@ -127,6 +126,21 @@ class ProfilPetaniController extends Controller
->groupByRaw($case)
->get();
$skorMultiKomponen = SkorPetani::query()
->join('petani', 'petani_skor.petani_id', '=', 'petani.id')
->whereIn('petani_id', $petani)
->whereIn('petani.komoditas_id', $komoditas->pluck('id'))
->selectRaw("$case AS segmen,
avg(skor_kesiapan_adopsi) as skor_kesiapan_adopsi,
avg(skor_komp_1_d4_k3_motivasi_kapasitas_adopsi) as skor_komp_1_d4_k3_motivasi_kapasitas_adopsi,
avg(skor_komp_2_d4_k2_ekonomi_rumah_tangga) as skor_komp_2_d4_k2_ekonomi_rumah_tangga,
avg(skor_komp_3_d2_praktik_budidaya_gap) as skor_komp_3_d2_praktik_budidaya_gap,
avg(skor_komp_4_d4_k4_keterlibatan_kelembagaan) as skor_komp_4_d4_k4_keterlibatan_kelembagaan,
avg(skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan) as skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan,
avg(skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar) as skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar")
->groupByRaw($case)
->get();
$petani = Petani::with(['skor'])
->whereIn('id', $petani)
->whereIn('komoditas_id', $komoditas->pluck('id'))
@@ -144,6 +158,7 @@ class ProfilPetaniController extends Controller
'skorDimensi',
'skorKomponen',
'skorMultiDimensi',
'skorMultiKomponen',
'petani',
));
}
@@ -34,12 +34,42 @@ class SummaryController extends Controller
$totalpetani = Profile::where('role', 'petani')->count();
$totallahan = Lahan::whereNotNull('path')->count();
$petaniList = Profile::where('role', 'petani')
->with(['lahan.tanaman.komoditas', 'desaKelurahan'])
$petaniList = Profile::select('id', 'nama', 'role', 'desa_kelurahan_id')
->where('role', 'petani')
->with([
'lahan:id,profile_id,luas_lahan',
'desaKelurahan:id,nama,kecamatan_id',
])
->paginate(20);
$allLahan = Lahan::whereNotNull('path')
->with(['profile', 'tanaman.komoditas', 'desaKelurahan.kecamatan.kabupatenKota.provinsi'])
$lahanSummaryByDesa = Lahan::whereNotNull('path')
->whereNotNull('desa_kelurahan_id')
->select('desa_kelurahan_id')
->selectRaw('COUNT(*) as total_lahan')
->selectRaw('COALESCE(SUM(luas_lahan), 0) as total_luas')
->groupBy('desa_kelurahan_id')
->get();
$desaList = DesaKelurahan::select('id', 'nama', 'path', 'kecamatan_id')
->whereIn('id', $lahanSummaryByDesa->pluck('desa_kelurahan_id')->filter()->unique()->values())
->with([
'kecamatan:id,nama,path,kabupaten_kota_id',
'kecamatan.kabupatenKota:id,nama,path,provinsi_id',
'kecamatan.kabupatenKota.provinsi:id,nama,path',
])
->get()
->keyBy('id');
$mapLahanLimit = min(max((int) $request->integer('map_lahan_limit', 500), 0), 2000);
$mapLahan = Lahan::whereNotNull('path')
->select('id', 'profile_id', 'desa_kelurahan_id', 'path', 'luas_lahan')
->with([
'profile:id,nama',
'tanaman:id,lahan_id,komoditas_id',
'tanaman.komoditas:id,nama',
])
->orderByDesc('updated_at')
->limit($mapLahanLimit)
->get();
$geoProvinsi = [];
@@ -48,47 +78,51 @@ class SummaryController extends Controller
$geoDesa = [];
$geoLahan = [];
foreach ($allLahan as $lahan) {
$desa = $lahan->desaKelurahan;
foreach ($lahanSummaryByDesa as $summary) {
$desa = $desaList->get($summary->desa_kelurahan_id);
$kec = $desa ? $desa->kecamatan : null;
$kab = $kec ? $kec->kabupatenKota : null;
$prov = $kab ? $kab->provinsi : null;
$totalLahan = (int) $summary->total_lahan;
$totalLuas = (float) $summary->total_luas;
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;
$geoProvinsi[$prov->id]['total_lahan'] += $totalLahan;
$geoProvinsi[$prov->id]['total_luas'] += $totalLuas;
}
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;
$geoKabupaten[$kab->id]['total_lahan'] += $totalLahan;
$geoKabupaten[$kab->id]['total_luas'] += $totalLuas;
}
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;
$geoKecamatan[$kec->id]['total_lahan'] += $totalLahan;
$geoKecamatan[$kec->id]['total_luas'] += $totalLuas;
}
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;
$geoDesa[$desa->id]['total_lahan'] += $totalLahan;
$geoDesa[$desa->id]['total_luas'] += $totalLuas;
}
}
foreach ($mapLahan as $lahan) {
$geoLahan[] = [
'id' => $lahan->id,
'parent_id' => $desa->id ?? null,
'parent_id' => $lahan->desa_kelurahan_id,
'polygon' => $lahan->path,
'nama_petani' => $lahan->profile->nama ?? 'N/A',
'luas' => $lahan->luas_lahan,
@@ -34,9 +34,16 @@ class PetaniController extends Controller
abort(403);
}
$provinsi = Provinsi::orderBy('kode', 'asc')->get();
$provinsi = Provinsi::select('id', 'kode', 'nama')->orderBy('kode', 'asc')->get();
$query = Petani::with('desakelurahan')
$query = Petani::with([
'desaKelurahan:id,nama,kecamatan_id',
'desaKelurahan.kecamatan:id,nama,kabupaten_kota_id',
'desaKelurahan.kecamatan.kabupatenKota:id,nama,provinsi_id',
'desaKelurahan.kecamatan.kabupatenKota.provinsi:id,nama',
'komoditas:id,nama',
'skor:id,petani_id,skor_kesiapan_adopsi',
])
->orderBy('created_at', 'desc');
if ($request->search) {
@@ -53,12 +60,12 @@ class PetaniController extends Controller
$summaryPetaniIds = (clone $query)->pluck('id');
$petani = $query->paginate($request->per_page ?? 10);
$komoditas = Komoditas::where('is_utama', true)->get();
$lahan = Lahan::whereIn('petani_id', $summaryPetaniIds)
->whereIn('komoditas_id', $komoditas->pluck('id'))
->get();
$tanaman = Tanaman::whereIn('lahan_id', $lahan->pluck('id'))
->get();
$komoditas = Komoditas::select('id', 'nama')->where('is_utama', true)->get();
$lahanQuery = Lahan::whereIn('petani_id', $summaryPetaniIds)
->whereIn('komoditas_id', $komoditas->pluck('id'));
$lahanIds = (clone $lahanQuery)->pluck('id');
$totalLuasLahan = (clone $lahanQuery)->sum('luas_lahan');
$totalTanaman = Tanaman::whereIn('lahan_id', $lahanIds)->count();
$case = "
CASE
@@ -74,7 +81,7 @@ class PetaniController extends Controller
->groupByRaw($case)
->get();
return view('produktivitas.petani.index', compact('petani', 'provinsi', 'lahan', 'komoditas', 'tanaman', 'skor'));
return view('produktivitas.petani.index', compact('petani', 'provinsi', 'komoditas', 'skor', 'totalLuasLahan', 'totalTanaman'));
}
public function create()
@@ -3,26 +3,43 @@
namespace App\Http\Controllers\Web\Produktivitas;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use App\Models\Pertanian\Petani;
use App\Models\Pertanian\SurveyProduktivitas;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
class SurveyProduktivitasController extends Controller
{
public function store($petaniId, Request $request)
{
$petani = Petani::findOrFail($petaniId);
$validated = $request->validate([
'produktivitas_komoditas' => ['required', 'array'],
'produktivitas_komoditas.*.komoditas_id' => ['nullable', 'exists:master_komoditas,id'],
'produktivitas_komoditas.*.hasil_panen_3_musim' => ['nullable', 'numeric'],
'produktivitas_komoditas.*.satuan' => ['nullable', 'string'],
$validator = Validator::make($request->all(), [
'produktivitas_komoditas' => ['required', 'array', 'min:1'],
'produktivitas_komoditas.*.komoditas_id' => ['required', 'exists:master_komoditas,id'],
'produktivitas_komoditas.*.hasil_panen_3_musim' => ['required', 'numeric', 'min:0'],
'produktivitas_komoditas.*.satuan' => ['required', 'in:ha_tahun,pohon_tahun'],
], [
'produktivitas_komoditas.required' => 'Minimal satu data produktivitas harus diisi.',
'produktivitas_komoditas.*.komoditas_id.required' => 'Komoditas wajib dipilih.',
'produktivitas_komoditas.*.komoditas_id.exists' => 'Komoditas yang dipilih tidak valid.',
'produktivitas_komoditas.*.hasil_panen_3_musim.required' => 'Hasil panen wajib diisi.',
'produktivitas_komoditas.*.hasil_panen_3_musim.numeric' => 'Hasil panen harus berupa angka.',
'produktivitas_komoditas.*.hasil_panen_3_musim.min' => 'Hasil panen tidak boleh kurang dari 0.',
'produktivitas_komoditas.*.satuan.required' => 'Satuan wajib dipilih.',
'produktivitas_komoditas.*.satuan.in' => 'Satuan yang dipilih tidak valid.',
]);
if ($validator->fails()) {
return $this->redirectBackToFragment($request)->withErrors($validator)->withInput();
}
$validated = $validator->validated();
foreach ($validated['produktivitas_komoditas'] as $row) {
SurveyProduktivitas::create([
'uid' => 'SPV-' . strtoupper(Str::random(10)),
'uid' => 'SPV-'.strtoupper(Str::random(10)),
'petani_id' => $petani->id,
'komoditas_id' => $row['komoditas_id'],
'kuantitas' => $row['hasil_panen_3_musim'],
@@ -51,10 +68,10 @@ class SurveyProduktivitasController extends Controller
{
$fragment = $request->input('redirect_fragment');
if (!is_string($fragment) || !preg_match('/^[A-Za-z0-9_-]+$/', $fragment)) {
if (! is_string($fragment) || ! preg_match('/^[A-Za-z0-9_-]+$/', $fragment)) {
return back();
}
return redirect()->to(Str::before(url()->previous(), '#') . '#' . $fragment);
return redirect()->to(Str::before(url()->previous(), '#').'#'.$fragment);
}
}
+108
View File
@@ -0,0 +1,108 @@
<?php
namespace App\Models\Bumdes;
use App\Enums\Bumdes\JabatanBumdes;
use App\Enums\Pendidikan;
use App\Models\User;
use App\Models\Wilayah\DesaKelurahan;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class PengurusBumdes extends Model
{
use SoftDeletes;
protected $table = 'bumdes_pengurus';
protected $fillable = [
'uid',
'nama',
'jenis_kelamin',
'tempat_lahir',
'tanggal_lahir',
'pendidikan_terakhir',
'alamat',
'desa_kelurahan_id',
'nomor_telepon',
'jabatan',
'jabatan_lainnya',
'lama_menjabat_tahun',
'tanggal_mulai_menjabat',
'created_by',
'updated_by',
'deleted_by',
];
protected $casts = [
'jenis_kelamin' => 'boolean',
'tanggal_lahir' => 'date',
'pendidikan_terakhir' => Pendidikan::class,
'tanggal_mulai_menjabat' => 'date',
'jabatan' => JabatanBumdes::class,
];
public function getUsiaAttribute(): ?int
{
if (! $this->tanggal_lahir) {
return null;
}
return Carbon::parse($this->tanggal_lahir)->age;
}
public function getLamaMenjabatAttribute(): string
{
if (! is_null($this->lama_menjabat_tahun)) {
return $this->lama_menjabat_tahun . ' tahun';
}
if (! $this->tanggal_mulai_menjabat) {
return '-';
}
$tanggalMulai = Carbon::parse($this->tanggal_mulai_menjabat)->startOfDay();
if ($tanggalMulai->isFuture()) {
return 'Belum mulai';
}
$selisih = $tanggalMulai->diff(Carbon::now());
$bagian = [];
if ($selisih->y > 0) {
$bagian[] = $selisih->y . ' tahun';
}
if ($selisih->m > 0) {
$bagian[] = $selisih->m . ' bulan';
}
if (empty($bagian)) {
return $selisih->d . ' hari';
}
return implode(' ', $bagian);
}
public function getNamaJabatanAttribute(): string
{
if ($this->jabatan === JabatanBumdes::LAINNYA && $this->jabatan_lainnya) {
return $this->jabatan_lainnya;
}
return $this->jabatan?->label() ?? '-';
}
public function desaKelurahan(): BelongsTo
{
return $this->belongsTo(DesaKelurahan::class, 'desa_kelurahan_id');
}
public function creator(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
}
+5 -5
View File
@@ -94,15 +94,15 @@ class Petani extends Model
protected static function booted(): void
{
static::saved(function (Petani $petani) {
$skor = SkorPetani::where('petani_id')->orderBy('id')->first();
if (! $skor) {
$skor = SkorPetani::where('petani_id', $petani->id)->orderBy('id')->first();
if (!$skor) {
$petaniUid = $petani->uid;
$part = explode('-', $petaniUid);
$skor = SkorPetani::create([
'uid' => 'SKR-'.$part[1].'-'.strtoupper(Str::random(10)),
'petani_id' => $petani->id,
'uid' => 'SKR-' . $part[1] . '-' . strtoupper(Str::random(10)),
'created_by' => $petani->created_by,
'updated_by' => $petani->updated_by,
'updated_by' => $petani->updated_by
]);
}
});
+11 -11
View File
@@ -102,7 +102,7 @@ class SkorPetani extends Model
$skorPetani->skor_d4_k5_1_kepemilikan_rekening +
$skorPetani->skor_d4_k5_2_pengalaman_kredit_formal +
$skorPetani->skor_d4_k5_3_kepemilikan_aset_produktif +
$skorPetani->skor_d4_k5_4_5_akses_program_bantuan
$skorPetani->skor_d4_k5_4_akses_program_bantuan
) / 4 +
(
$skorPetani->skor_d4_k6_3_keberadaan_hutang_terkait_panen +
@@ -119,23 +119,23 @@ class SkorPetani extends Model
$skorPetani->skor_d2_sistem_praktik_budidaya = (
$skorPetani->skor_komp_3_d2_praktik_budidaya_gap
);
$skorPetani->skor_d4_sosial_ekonomi = (
$skorPetani->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi
);
$skorPetani->skor_d6_rantai_nilai_akses_pasar = (
$skorPetani->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar * 0.25 +
$skorPetani->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar
);
$skorPetani->skor_d4_sosial_ekonomi = (
$skorPetani->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi * 0.25 +
$skorPetani->skor_komp_2_d4_k2_ekonomi_rumah_tangga * 0.20 +
$skorPetani->skor_komp_4_d4_k4_keterlibatan_kelembagaan * 0.15 +
$skorPetani->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan * 0.10
) / 0.70;
$skorPetani->skor_kesiapan_adopsi = (
$skorPetani->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar * 0.25 +
$skorPetani->skor_komp_2_d4_k2_ekonomi_rumah_tangga * 0.20 +
$skorPetani->skor_komp_3_d2_praktik_budidaya_gap * 0.20 +
$skorPetani->skor_komp_4_d4_k4_keterlibatan_kelembagaan * 0.15 +
$skorPetani->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan * 0.10 +
$skorPetani->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi * 0.10
$skorPetani->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi * 0.25 + // D4
$skorPetani->skor_komp_2_d4_k2_ekonomi_rumah_tangga * 0.20 + // D4
$skorPetani->skor_komp_3_d2_praktik_budidaya_gap * 0.20 + // D2
$skorPetani->skor_komp_4_d4_k4_keterlibatan_kelembagaan * 0.15 + // D4
$skorPetani->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan * 0.10 + // D4
$skorPetani->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar * 0.10 // D6
);
});
}
@@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('bumdes_pengurus', function (Blueprint $table) {
$table->id();
$table->string('uid')->unique();
$table->string('nama');
$table->boolean('jenis_kelamin');
$table->string('tempat_lahir')->nullable();
$table->date('tanggal_lahir');
$table->string('pendidikan_terakhir')->nullable();
$table->text('alamat')->nullable();
$table->foreignId('desa_kelurahan_id')->nullable()->constrained('master_desa_kelurahan')->onDelete('set null');
$table->string('nomor_telepon')->nullable();
$table->string('jabatan');
$table->string('jabatan_lainnya')->nullable();
$table->unsignedSmallInteger('lama_menjabat_tahun')->nullable();
$table->date('tanggal_mulai_menjabat');
$table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('bumdes_pengurus');
}
};
@@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('bumdes_pengurus', function (Blueprint $table) {
if (! Schema::hasColumn('bumdes_pengurus', 'pendidikan_terakhir')) {
$table->string('pendidikan_terakhir')->nullable()->after('tanggal_lahir');
}
if (! Schema::hasColumn('bumdes_pengurus', 'jabatan_lainnya')) {
$table->string('jabatan_lainnya')->nullable()->after('jabatan');
}
if (! Schema::hasColumn('bumdes_pengurus', 'lama_menjabat_tahun')) {
$table->unsignedSmallInteger('lama_menjabat_tahun')->nullable()->after('jabatan_lainnya');
}
});
}
public function down(): void
{
Schema::table('bumdes_pengurus', function (Blueprint $table) {
if (Schema::hasColumn('bumdes_pengurus', 'lama_menjabat_tahun')) {
$table->dropColumn('lama_menjabat_tahun');
}
if (Schema::hasColumn('bumdes_pengurus', 'jabatan_lainnya')) {
$table->dropColumn('jabatan_lainnya');
}
if (Schema::hasColumn('bumdes_pengurus', 'pendidikan_terakhir')) {
$table->dropColumn('pendidikan_terakhir');
}
});
}
};
@@ -0,0 +1,7 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@include('bumdes.profil.header', ['pengurus' => $pengurus])
</div>
@endsection
@@ -0,0 +1,280 @@
@php
$prefix = $mode . '-bumdes';
$currentProvinsiId = old('provinsi_id', $pengurus?->desaKelurahan?->kecamatan?->kabupatenKota?->provinsi_id);
$currentKabupaten = $pengurus?->desaKelurahan?->kecamatan?->kabupatenKota;
$currentKecamatan = $pengurus?->desaKelurahan?->kecamatan;
$currentDesa = $pengurus?->desaKelurahan;
$currentJabatan = $pengurus?->jabatan instanceof \App\Enums\Bumdes\JabatanBumdes ? $pengurus->jabatan->value : $pengurus?->jabatan;
$currentPendidikan = $pengurus?->pendidikan_terakhir instanceof \App\Enums\Pendidikan ? $pengurus->pendidikan_terakhir->value : $pengurus?->pendidikan_terakhir;
@endphp
<h5 class="pb-4 border-bottom mb-4">Data Pribadi</h5>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-nama">Nama Pengurus BUMDes<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('nama') is-invalid @enderror" id="{{ $prefix }}-nama" name="nama" placeholder="Contoh: John Doe" value="{{ old('nama', $pengurus?->nama) }}" />
@error('nama')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-jenis-kelamin">Jenis Kelamin<span class="text-danger">*</span></label>
<select class="form-control @error('jenis_kelamin') is-invalid @enderror" id="{{ $prefix }}-jenis-kelamin" name="jenis_kelamin">
<option value="">Pilih Jenis Kelamin</option>
<option value="1" {{ old('jenis_kelamin', $pengurus?->jenis_kelamin) == '1' ? 'selected' : '' }}>Laki-laki</option>
<option value="0" {{ old('jenis_kelamin', $pengurus?->jenis_kelamin) == '0' ? 'selected' : '' }}>Perempuan</option>
</select>
@error('jenis_kelamin')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-tempat-lahir">Tempat Lahir<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('tempat_lahir') is-invalid @enderror" id="{{ $prefix }}-tempat-lahir" name="tempat_lahir" placeholder="Contoh: Ngada" value="{{ old('tempat_lahir', $pengurus?->tempat_lahir) }}" />
@error('tempat_lahir')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-tanggal-lahir">Tanggal Lahir<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('tanggal_lahir') is-invalid @enderror" id="{{ $prefix }}-tanggal-lahir" name="tanggal_lahir" value="{{ old('tanggal_lahir', $pengurus?->tanggal_lahir?->format('d-m-Y')) }}" />
@error('tanggal_lahir')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-pendidikan-terakhir">Pendidikan Terakhir<span class="text-danger">*</span></label>
<select class="form-control @error('pendidikan_terakhir') is-invalid @enderror" id="{{ $prefix }}-pendidikan-terakhir" name="pendidikan_terakhir">
<option value="">Pilih Pendidikan Terakhir</option>
@foreach($pendidikan as $value)
<option value="{{ $value['value'] }}" {{ old('pendidikan_terakhir', $currentPendidikan) == $value['value'] ? 'selected' : '' }}>{{ $value['label'] }}</option>
@endforeach
</select>
@error('pendidikan_terakhir')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Peran Kepengurusan BUMDes</h5>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-jabatan">Jabatan/Peran<span class="text-danger">*</span></label>
<select class="form-control @error('jabatan') is-invalid @enderror" id="{{ $prefix }}-jabatan" name="jabatan">
<option value="">Pilih Jabatan/Peran</option>
@foreach($jabatan as $value)
<option value="{{ $value['value'] }}" {{ old('jabatan', $currentJabatan) == $value['value'] ? 'selected' : '' }}>{{ $value['label'] }}</option>
@endforeach
</select>
@error('jabatan')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation {{ old('jabatan', $currentJabatan) === \App\Enums\Bumdes\JabatanBumdes::LAINNYA->value ? '' : 'd-none' }}" id="{{ $prefix }}-jabatan-lainnya-wrapper">
<label class="form-label" for="{{ $prefix }}-jabatan-lainnya">Jabatan Lainnya<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('jabatan_lainnya') is-invalid @enderror" id="{{ $prefix }}-jabatan-lainnya" name="jabatan_lainnya" placeholder="Contoh: Kepala Unit Usaha" value="{{ old('jabatan_lainnya', $pengurus?->jabatan_lainnya) }}" />
@error('jabatan_lainnya')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-lama-menjabat">Lama Menjabat (Tahun)<span class="text-danger">*</span></label>
<input type="number" min="0" max="80" class="form-control @error('lama_menjabat_tahun') is-invalid @enderror" id="{{ $prefix }}-lama-menjabat" name="lama_menjabat_tahun" placeholder="Contoh: 2" value="{{ old('lama_menjabat_tahun', $pengurus?->lama_menjabat_tahun) }}" />
@error('lama_menjabat_tahun')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<h5 class="pb-4 border-bottom mb-4 mt-4">Domisili dan Kontak</h5>
<div class="row">
<div class="col-md-12 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-alamat">Alamat<span class="text-danger">*</span></label>
<textarea class="form-control @error('alamat') is-invalid @enderror" id="{{ $prefix }}-alamat" name="alamat" rows="2" placeholder="Contoh: Jl. Nama Jalan, Nama Dusun">{{ old('alamat', $pengurus?->alamat) }}</textarea>
@error('alamat')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-provinsi">Provinsi<span class="text-danger">*</span></label>
<select class="form-control @error('provinsi_id') is-invalid @enderror" id="{{ $prefix }}-provinsi" name="provinsi_id">
<option value="">Pilih Provinsi</option>
@foreach($provinsi as $p)
<option value="{{ $p->id }}" {{ $currentProvinsiId == $p->id ? 'selected' : '' }}>{{ $p->nama }}</option>
@endforeach
</select>
@error('provinsi_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-kabupaten">Kabupaten/Kota<span class="text-danger">*</span></label>
<select class="form-control @error('kabupaten_id') is-invalid @enderror" id="{{ $prefix }}-kabupaten" name="kabupaten_id">
<option value="">Pilih Kabupaten/Kota</option>
@if($currentKabupaten)
<option value="{{ $currentKabupaten->id }}" selected>{{ $currentKabupaten->nama }}</option>
@endif
</select>
@error('kabupaten_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-kecamatan">Kecamatan<span class="text-danger">*</span></label>
<select class="form-control @error('kecamatan_id') is-invalid @enderror" id="{{ $prefix }}-kecamatan" name="kecamatan_id">
<option value="">Pilih Kecamatan</option>
@if($currentKecamatan)
<option value="{{ $currentKecamatan->id }}" selected>{{ $currentKecamatan->nama }}</option>
@endif
</select>
@error('kecamatan_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-desa">Desa/Kelurahan<span class="text-danger">*</span></label>
<select class="form-control @error('desa_kelurahan_id') is-invalid @enderror" id="{{ $prefix }}-desa" name="desa_kelurahan_id">
<option value="">Pilih Desa/Kelurahan</option>
@if($currentDesa)
<option value="{{ $currentDesa->id }}" selected>{{ $currentDesa->nama }}</option>
@endif
</select>
@error('desa_kelurahan_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="{{ $prefix }}-nomor-telepon">No HP</label>
<input type="text" class="form-control @error('nomor_telepon') is-invalid @enderror" id="{{ $prefix }}-nomor-telepon" name="nomor_telepon" placeholder="Contoh: 081234567890" value="{{ old('nomor_telepon', $pengurus?->nomor_telepon) }}" minlength="11" maxlength="13" />
@error('nomor_telepon')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
const prefix = '#{{ $prefix }}';
const lainnyaValue = '{{ \App\Enums\Bumdes\JabatanBumdes::LAINNYA->value }}';
$(`${prefix}-jenis-kelamin, ${prefix}-pendidikan-terakhir, ${prefix}-jabatan`).select2();
$(`${prefix}-tanggal-lahir`).flatpickr({
dateFormat: 'd-m-Y'
});
function toggleJabatanLainnya() {
const isLainnya = $(`${prefix}-jabatan`).val() === lainnyaValue;
$(`${prefix}-jabatan-lainnya-wrapper`).toggleClass('d-none', !isLainnya);
if (!isLainnya) {
$(`${prefix}-jabatan-lainnya`).val('');
}
}
$(`${prefix}-jabatan`).on('change', toggleJabatanLainnya);
toggleJabatanLainnya();
$(`${prefix}-provinsi`).select2().change(function(e) {
e.preventDefault();
const provinsiId = $(this).val();
$(`${prefix}-kabupaten`).prop('disabled', !provinsiId).val('').trigger('change');
$(`${prefix}-kecamatan`).prop('disabled', true).val('').trigger('change');
$(`${prefix}-desa`).prop('disabled', true).val('').trigger('change');
if (provinsiId) {
$.ajax({
url: '{{ route("kabupatenkota.byprovinsi", ":id") }}'.replace(':id', provinsiId),
method: 'GET',
success: function(data) {
$(`${prefix}-kabupaten`).empty().append('<option value="">Pilih Kabupaten/Kota</option>');
data.forEach(function(kabupaten) {
$(`${prefix}-kabupaten`).append('<option value="' + kabupaten.id + '">' + kabupaten.nama + '</option>');
});
}
});
}
});
$(`${prefix}-kabupaten`).select2().change(function(e) {
e.preventDefault();
const kabupatenId = $(this).val();
$(`${prefix}-kecamatan`).prop('disabled', !kabupatenId).val('').trigger('change');
$(`${prefix}-desa`).prop('disabled', true).val('').trigger('change');
if (kabupatenId) {
$.ajax({
url: '{{ route("kecamatan.bykabupatenkota", ":id") }}'.replace(':id', kabupatenId),
method: 'GET',
success: function(data) {
$(`${prefix}-kecamatan`).empty().append('<option value="">Pilih Kecamatan</option>');
data.forEach(function(kecamatan) {
$(`${prefix}-kecamatan`).append('<option value="' + kecamatan.id + '">' + kecamatan.nama + '</option>');
});
}
});
}
});
$(`${prefix}-kecamatan`).select2().change(function(e) {
e.preventDefault();
const kecamatanId = $(this).val();
$(`${prefix}-desa`).prop('disabled', !kecamatanId).val('').trigger('change');
if (kecamatanId) {
$.ajax({
url: '{{ route("desakelurahan.bykecamatan", ":id") }}'.replace(':id', kecamatanId),
method: 'GET',
success: function(data) {
$(`${prefix}-desa`).empty().append('<option value="">Pilih Desa/Kelurahan</option>');
data.forEach(function(desa) {
$(`${prefix}-desa`).append('<option value="' + desa.id + '">' + desa.nama + '</option>');
});
}
});
}
});
$(`${prefix}-desa`).select2();
$('#{{ $mode }}BumdesForm').validate({
rules: {
nama: { required: true },
jenis_kelamin: { required: true },
tempat_lahir: { required: true },
tanggal_lahir: { required: true },
pendidikan_terakhir: { required: true },
jabatan: { required: true },
jabatan_lainnya: {
required: function() {
return $(`${prefix}-jabatan`).val() === lainnyaValue;
}
},
lama_menjabat_tahun: { required: true, digits: true, min: 0, max: 80 },
alamat: { required: true },
provinsi_id: { required: true },
kabupaten_id: { required: true },
kecamatan_id: { required: true },
desa_kelurahan_id: { required: true },
nomor_telepon: { required: false, digits: true, minlength: 11, maxlength: 13 }
},
messages: {
nama: { required: 'Nama pengurus BUMDes wajib diisi' },
jenis_kelamin: { required: 'Jenis kelamin wajib dipilih' },
tempat_lahir: { required: 'Tempat lahir wajib diisi' },
tanggal_lahir: { required: 'Tanggal lahir wajib diisi' },
pendidikan_terakhir: { required: 'Pendidikan terakhir wajib dipilih' },
jabatan: { required: 'Jabatan/peran wajib dipilih' },
jabatan_lainnya: { required: 'Jabatan lainnya wajib diisi' },
lama_menjabat_tahun: {
required: 'Lama menjabat wajib diisi',
digits: 'Lama menjabat harus berupa angka tahun',
min: 'Lama menjabat tidak boleh kurang dari 0 tahun',
max: 'Lama menjabat tidak boleh lebih dari 80 tahun'
},
alamat: { required: 'Alamat wajib diisi' },
provinsi_id: { required: 'Provinsi wajib dipilih' },
kabupaten_id: { required: 'Kabupaten/Kota wajib dipilih' },
kecamatan_id: { required: 'Kecamatan wajib dipilih' },
desa_kelurahan_id: { required: 'Desa/Kelurahan wajib dipilih' },
nomor_telepon: {
digits: 'Nomor telepon harus berupa angka',
minlength: 'Nomor telepon minimal 11 digit',
maxlength: 'Nomor telepon maksimal 13 digit'
}
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
element.closest('.form-control-validation').append(error);
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
}
});
});
</script>
@endpush
@@ -0,0 +1,34 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@if ($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@include('bumdes.profil.header', ['pengurus' => null])
<div class="card mb-6">
<div class="card-header border-bottom">
<h5 class="card-title mb-0">Tambah Profil Pengurus BUMDes</h5>
</div>
<div class="card-body pt-6">
<form id="addBumdesForm" action="{{ route('bumdes.store') }}" method="POST">
@csrf
@include('bumdes.profil._form', ['pengurus' => null, 'mode' => 'add'])
<div class="mt-4 text-end">
<a href="{{ route('bumdes.index') }}" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
<button type="submit" class="btn btn-success data-submit wave-effect wave-light"><i class="ti tabler-device-floppy me-2"></i> Simpan Profil</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@@ -0,0 +1,39 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if ($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@include('bumdes.profil.header', ['pengurus' => $pengurus])
<div class="card mb-6">
<div class="card-header border-bottom">
<h5 class="card-title mb-0">Edit Profil Pengurus BUMDes</h5>
</div>
<div class="card-body pt-6">
<form id="editBumdesForm" action="{{ route('bumdes.update', $pengurus->id) }}" method="POST">
@csrf
@method('PUT')
@include('bumdes.profil._form', ['pengurus' => $pengurus, 'mode' => 'edit'])
<div class="mt-4 text-end">
<a href="{{ route('bumdes.index') }}" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
<button type="submit" class="btn btn-success data-submit wave-effect wave-light"><i class="ti tabler-device-floppy me-2"></i> Simpan Profil</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@@ -0,0 +1,162 @@
<style>
@media (min-width: 768px) {
.nav-pills-custom-spacing {
display: flex;
width: 100%;
gap: 0.5rem;
flex-wrap: nowrap !important;
overflow-x: auto;
}
.nav-pills-custom-spacing::-webkit-scrollbar {
display: none;
}
.nav-pills-custom-spacing .nav-item {
margin-right: 0 !important;
flex: 1;
}
.nav-pills-custom-spacing .nav-link {
display: flex;
justify-content: center;
align-items: center;
padding-left: 0.5rem !important;
padding-right: 0.5rem !important;
width: 100%;
white-space: nowrap;
font-size: 0.9375rem !important;
}
.nav-pills-custom-spacing .nav-link i {
margin-right: 0.4rem !important;
}
}
</style>
@php
$jenisKelamin = isset($pengurus)
? ($pengurus->jenis_kelamin ? 'Laki-laki' : 'Perempuan')
: 'Jenis Kelamin';
$jabatanLabel = isset($pengurus) ? $pengurus->nama_jabatan : 'Jabatan/Peran';
$domisili = isset($pengurus) && $pengurus->desaKelurahan
? $pengurus->desaKelurahan->nama . ', ' . $pengurus->desaKelurahan->kecamatan?->nama . ', ' . $pengurus->desaKelurahan->kecamatan?->kabupatenKota?->nama . ', ' . $pengurus->desaKelurahan->kecamatan?->kabupatenKota?->provinsi?->nama
: 'Desa/Kelurahan, Kecamatan, Kabupaten/Kota, Provinsi';
@endphp
<div class="row mb-4">
<div class="col-md-4 mb-2 mb-md-0">
<div class="card h-100">
<div class="card-body p-3">
<h6 class="card-title mb-2">Profil Pengurus BUMDes</h6>
<div class="d-flex justify-content-start align-items-center mb-3">
<div class="avatar me-2">
<span class="avatar-initial rounded bg-label-primary">
<i class="icon-base ti tabler-user-check icon-22px"></i>
</span>
</div>
<div class="d-flex flex-column">
<h6 class="mb-0" style="font-size: 0.9rem;">{{ isset($pengurus) ? $pengurus->nama : 'Tambah Pengurus BUMDes Baru' }}</h6>
<span class="text-muted" style="font-size: 0.75rem;">{{ $jenisKelamin }}</span>
<span class="text-muted" style="font-size: 0.75rem;">Jabatan: {{ $jabatanLabel }}</span>
</div>
</div>
<hr class="my-2">
<h6 class="mb-1" style="font-size: 0.85rem;">Domisili</h6>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Alamat: {{ isset($pengurus) ? $pengurus->alamat : 'Alamat' }}</p>
<p class="mb-0 text-muted" style="font-size: 0.75rem; line-height: 1.3;">{{ $domisili }}</p>
</div>
</div>
</div>
<div class="col-md-8 d-flex flex-column">
<div class="card mb-2 flex-grow-1">
<div class="card-widget-separator-wrapper h-100">
<div class="card-body card-widget-separator py-2 h-100 d-flex flex-column justify-content-center">
<div class="row gy-2">
<div class="col-sm-6 col-lg-4">
<div class="d-flex justify-content-between align-items-center card-widget-1 border-end h-100 pe-3">
<div>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Jenis Kelamin</p>
<h5 class="mb-0">{{ $jenisKelamin }}</h5>
<p class="mb-0" style="font-size: 0.75rem;">
<span class="me-1">{{ isset($pengurus) ? ($pengurus->usia . ' tahun') : 'Belum terisi' }}</span>
</p>
</div>
<span class="avatar">
<span class="avatar-initial rounded">
<i class="icon-base ti tabler-users icon-22px text-heading"></i>
</span>
</span>
</div>
</div>
<div class="col-sm-6 col-lg-4">
<div class="d-flex justify-content-between align-items-center card-widget-1 border-end h-100 px-3">
<div>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Jabatan</p>
<h5 class="mb-0">{{ $jabatanLabel }}</h5>
<p class="mb-0" style="font-size: 0.75rem;">
<span class="me-1">{{ isset($pengurus) ? $pengurus->lama_menjabat : 'Belum terisi' }}</span>
</p>
</div>
<span class="avatar">
<span class="avatar-initial rounded">
<i class="icon-base ti tabler-briefcase icon-22px text-heading"></i>
</span>
</span>
</div>
</div>
<div class="col-sm-6 col-lg-4">
<div class="d-flex justify-content-between align-items-center card-widget-1 h-100 ps-3">
<div>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Domisili</p>
<h5 class="mb-0">{{ isset($pengurus) ? ($pengurus->desaKelurahan?->nama ?? '-') : '-' }}</h5>
<p class="mb-0" style="font-size: 0.75rem;">
<span class="me-1">{{ isset($pengurus) ? ($pengurus->desaKelurahan?->kecamatan?->nama ?? '-') : 'Belum terisi' }}</span>
</p>
</div>
<span class="avatar">
<span class="avatar-initial rounded">
<i class="icon-base ti tabler-map-pin icon-22px text-heading"></i>
</span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card flex-grow-1">
<div class="card-body py-3 d-flex align-items-center">
<div class="w-100">
<p class="mb-1 text-muted" style="font-size: 0.75rem;">Alamat Domisili</p>
<h6 class="mb-0">{{ isset($pengurus) ? ($pengurus->alamat ?: '-') : '-' }}</h6>
<p class="mb-0 text-muted" style="font-size: 0.75rem;">{{ $domisili }}</p>
</div>
</div>
</div>
</div>
</div>
<div class="nav-align-top">
<ul class="nav nav-pills flex-column flex-md-row mb-6 row-gap-2 nav-pills-custom-spacing">
<li class="nav-item">
<a class="nav-link {{ request()->routeIs('bumdes.create') || request()->routeIs('bumdes.edit') ? 'active' : '' }}" href="{{ isset($pengurus) ? route('bumdes.edit', $pengurus->id) : route('bumdes.create') }}">
<i class="icon-base ti tabler-user-check icon-sm"></i>Profil
</a>
</li>
<li class="nav-item">
@if(isset($pengurus))
<a class="nav-link {{ request()->routeIs('bumdes.kelembagaan-aktor.*') ? 'active' : '' }}" href="{{ route('bumdes.kelembagaan-aktor.index', $pengurus->id) }}">
<i class="icon-base ti tabler-building-community icon-sm"></i>Kelembagaan dan Aktor
</a>
@else
<a class="nav-link" href="#" disabled data-bs-original-title="Kelembagaan dan Aktor, isi profil terlebih dahulu" data-bs-toggle="tooltip" data-bs-placement="top">
<i class="icon-base ti tabler-building-community icon-sm"></i>Kelembagaan dan Aktor
</a>
@endif
</li>
</ul>
</div>
@@ -0,0 +1,158 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="d-flex flex-row gap-3 mb-4">
<div class="w-25">
<x-summary-card
title="Pengurus BUMDes"
count="{{ $totalPengurus }}"
subtitle="{{ $totalLakiLaki }} Laki-laki, {{ $totalPerempuan }} Perempuan"
icon="user-check"
color="primary"
/>
</div>
<div class="w-25">
<x-summary-card
title="Desa/Kelurahan"
count="{{ $totalDesaKelurahan }}"
subtitle="desa/kelurahan memiliki data pengurus"
icon="map-pin"
color="success"
/>
</div>
<div class="w-25">
<x-summary-card
title="Jabatan/Peran"
count="{{ $totalJabatan }}"
subtitle="jenis jabatan/peran terdata"
icon="briefcase"
color="info"
/>
</div>
</div>
<div class="card">
<div class="card-header border-bottom">
<h5 class="card-title mb-0">Data Pengurus BUMDes</h5>
</div>
<div class="card-body border-bottom pt-4">
<form method="GET" action="{{ route('bumdes.index') }}" class="d-flex justify-content-between align-items-center row gap-3 gap-md-0">
<div class="col-md-auto">
<div class="d-flex align-items-center">
<label class="me-2 text-nowrap">Show</label>
<select name="per_page" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
<option value="10" {{ request('per_page') == 10 ? 'selected' : '' }}>10</option>
<option value="25" {{ request('per_page') == 25 ? 'selected' : '' }}>25</option>
</select>
<label class="ms-2 text-nowrap">entries</label>
</div>
</div>
<div class="col-md-auto d-flex gap-2">
<div class="input-group input-group-sm w-auto">
<input type="text" name="search" class="form-control" placeholder="Cari Nama..." value="{{ request('search') }}">
<button type="submit" class="btn btn-outline-primary"><i class="ti tabler-search"></i></button>
</div>
<a href="{{ route('bumdes.create') }}" class="btn btn-sm btn-primary">
<i class="ti tabler-plus me-1"></i> Tambah
</a>
</div>
</form>
</div>
<div class="table-responsive text-nowrap">
<table class="table table-hover">
<thead class="border-top">
<tr>
<th>No</th>
<th>Nama</th>
<th>Jenis Kelamin</th>
<th>Usia</th>
<th>Desa/Kelurahan</th>
<th>Jabatan/Peran</th>
<th>Lama Menjabat</th>
@if($showEnumerator)
<th>Nama Enumerator</th>
@endif
<th>Aksi</th>
</tr>
</thead>
<tbody>
@forelse($pengurus as $item)
<tr>
<td>{{ ($pengurus->firstItem() ?? 0) + $loop->index }}</td>
<td><span class="text-heading">{{ $item->nama }}</span></td>
<td><span class="text-muted">{{ $item->jenis_kelamin ? 'Laki-laki' : 'Perempuan' }}</span></td>
<td><span class="text-muted">{{ $item->usia }} tahun</span></td>
<td>
<span class="text-muted">
{{ $item->desaKelurahan?->nama }},
{{ $item->desaKelurahan?->kecamatan?->nama }},
{{ $item->desaKelurahan?->kecamatan?->kabupatenKota?->nama }},
{{ $item->desaKelurahan?->kecamatan?->kabupatenKota?->provinsi?->nama }}
</span>
</td>
<td>{{ $item->nama_jabatan }}</td>
<td><span class="text-muted">{{ $item->lama_menjabat }}</span></td>
@if($showEnumerator)
<td><span class="text-muted">{{ $item->creator?->name ?? '-' }}</span></td>
@endif
<td>
<div class="d-flex align-items-center">
<a href="{{ route('bumdes.edit', $item->id) }}" class="btn btn-icon btn-text-secondary rounded-pill edit-record"><i class="ti tabler-edit ti-md"></i></a>
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $item->id }}" data-nama="{{ $item->nama }}"><i class="ti tabler-trash ti-md"></i></a>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="{{ $showEnumerator ? 9 : 8 }}" class="text-center py-4">Tidak ada data ditemukan.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="card-footer d-flex justify-content-center justify-content-md-end border-top">
{{ $pengurus->appends(request()->query())->links('pagination::bootstrap-5') }}
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
const csrfToken = "{{ csrf_token() }}";
$(document).ready(function () {
$(document).on('click', '.delete-record', function () {
const id = $(this).data('id');
const name = $(this).data('nama');
Swal.fire({
title: 'Apakah Anda yakin?',
text: `Profile "${name}" akan dihapus secara permanen!`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, Hapus!',
customClass: { confirmButton: 'btn btn-primary me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.value) {
$.ajax({
url: '{{ route('bumdes.destroy', ':id') }}'.replace(':id', id),
type: 'DELETE',
headers: { 'X-CSRF-TOKEN': csrfToken },
success: function (res) {
Swal.fire({ icon: 'success', title: 'Terhapus!', text: res.message, showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
},
error: () => Swal.fire({ icon: 'error', title: 'Gagal!', text: 'Terjadi kesalahan sistem.' })
});
}
});
});
});
</script>
@endpush
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,580 @@
@extends('layout.main')
@section('content')
@php
$segments = [
[
'name' => 'Penggerak',
'range' => '4.0 - 5.0',
'icon' => 'tabler-crown',
'color' => 'success',
],
[
'name' => 'Perintis',
'range' => '3.0 - 3.9',
'icon' => 'tabler-flag',
'color' => 'info',
],
[
'name' => 'Pemerhati',
'range' => '2.0 - 2.9',
'icon' => 'tabler-eye',
'color' => 'warning',
],
[
'name' => 'Pemula',
'range' => '1.0 - 1.9',
'icon' => 'tabler-seedling',
'color' => 'danger',
],
];
$colors = collect($segments)
->pluck('color')
->map(fn($c) => "var(--bs-{$c})")
->values();
$countSegmentasi = $countSegmentasi->keyBy('segmen');
$seriesSegmentasi = collect($segments)->map(function ($segment) use ($countSegmentasi) {
return $countSegmentasi[$segment['name']]->total ?? 0;
});
$seriesSegmentasiKomoditas = collect($segments)->map(function ($segment) use ($countSegmentasiByKomoditas, $komoditas) {
return [
'name' => $segment['name'],
'data' => $komoditas->map(function ($item) use ($countSegmentasiByKomoditas, $segment) {
return optional(
$countSegmentasiByKomoditas->first(function ($row) use ($item, $segment) {
return $row->komoditas_id == $item->id
&& $row->segmen == $segment['name'];
})
)->total ?? 0;
})->values(),
];
})->values();
@endphp
<div class="container-xxl flex-grow-1 container-p-y">
<div class="row g-6">
<div class="col-lg-3 col-sm-6">
<div class="card card-border-shadow-primary h-100">
<div class="card-body">
<div class="d-flex align-items-center mb-2">
<div class="avatar me-4">
<span class="avatar-initial rounded bg-label-primary">
<i class="icon-base ti tabler-user-check icon-28px"></i>
</span>
</div>
<h4 class="mb-0">{{ $countPetani }}</h4>
</div>
<p class="mb-1">Total Petani</p>
<p class="mb-0">
<span class="text-heading fw-medium me-2">{{ $countKomoditas }}</span>
<small class="text-body-secondary">komoditas utama</small>
</p>
</div>
</div>
</div>
<div class="col-lg-3 col-sm-6">
<div class="card card-border-shadow-warning h-100">
<div class="card-body">
<div class="d-flex align-items-center mb-2">
<div class="avatar me-4">
<span class="avatar-initial rounded bg-label-warning">
<i class="icon-base ti tabler-trees icon-28px"></i>
</span>
</div>
<h4 class="mb-0">{{ number_format($sumLahan, 2, ',', '.') }} ha</h4>
</div>
<p class="mb-1">Total Luas Lahan</p>
<p class="mb-0">
<small class="text-body-warning">rata-rata</small>
<span class="text-heading fw-medium">{{ number_format($avgLahan, 2, ',', '.') }}</span>
<small class="text-body-warning">ha/petani</small>
</p>
</div>
</div>
</div>
<div class="col-lg-3 col-sm-6">
<div class="card card-border-shadow-info h-100">
<div class="card-body">
<div class="d-flex align-items-center mb-2">
<div class="avatar me-4">
<span class="avatar-initial rounded bg-label-info">
<i class="icon-base ti tabler-star icon-28px"></i>
</span>
</div>
<h4 class="mb-0">{{ number_format($avgSkor, 2, ',', '.') }}</h4>
</div>
<p class="mb-1">Rata-rata Indeks Kesiapan Adopsi</p>
<p class="mb-0">
<small class="text-body-secondary">Segmentasi:</small>
<span class="text-heading fw-medium me-2">{{ $avgSegmen }}</span>
</p>
</div>
</div>
</div>
<div class="col-lg-3 col-sm-6">
<div class="card card-border-shadow-success h-100">
<div class="card-body">
<div class="d-flex align-items-center mb-2">
<div class="avatar me-4">
<span class="avatar-initial rounded bg-label-success">
<i class="icon-base ti tabler-map-2 icon-28px"></i>
</span>
</div>
<h4 class="mb-0">{{ $countDesa }}</h4>
</div>
<p class="mb-1">Jumlah Desa Sasaran</p>
<p class="mb-0">
<span class="text-heading fw-medium me-2">{{ $countKecamatan }}</span>
<small class="text-body-secondary">kecamatan sasaran</small>
</p>
</div>
</div>
</div>
</div>
<div class="row g-6 py-4">
<div class="col-lg-6 col-sm-12">
<div class="card card-border-shadow-primary h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<div class="card-title mb-0">
<h5 class="m-0 me-2">Distribusi Segmentasi Petani</h5>
<p class="card-subtitle">untuk semua komoditas</p>
</div>
</div>
<div class="card-body">
<div class="d-flex justify-content-start align-items-start mb-3">
<div id="chart-segmentasi-petani"></div>
<table class="table card-table table-border-top-0 table-border-bottom-0 data-table">
<thead>
<tr>
<th></th>
<th class="text-end pe-0">Petani</th>
<th class="text-end pe-0">%</th>
</tr>
</thead>
<tbody>
@foreach ($segments as $segment)
@php
$total = $countSegmentasi->where('segmen', $segment['name'])->sum('total');
$persen = $countPetani ? ($total / $countPetani) * 100 : 0;
@endphp
<tr>
<td>
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti {{ $segment['icon'] }} icon-lg text-{{ $segment['color'] }}"></i>
</div>
<span class="text-{{ $segment['color'] }}">
{{ $segment['name'] }}
</span>
</div>
</td>
<td class="text-end pe-0">{{ number_format($total) }}</td>
<td class="text-end pe-0">{{ number_format($persen, 2) }}%</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="col-lg-6 col-sm-12">
<div class="card card-border-shadow-secondary h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<div class="card-title mb-0">
<h5 class="m-0 me-2">Distribusi Segmentasi Petani</h5>
<p class="card-subtitle">per komoditas</p>
</div>
</div>
<div class="card-body">
<div id="chart-segmentasi-petani-komoditas"></div>
</div>
</div>
</div>
</div>
<div class="row g-6 py-4">
<div class="col-lg-6 col-sm-12">
<div class="card h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<div class="card-title mb-0">
<h5 class="m-0 me-2">Rata-rata Dimensi Kesiapan Adopsi</h5>
<p class="card-subtitle">untuk semua komoditas</p>
</div>
</div>
<div class="card-body">
<div id="chart-dimensi"></div>
<div class="d-flex flex-wrap gap-3 mt-3 small justify-content-center">
<div>
<span class="badge bg-label-primary">D1</span> Sistem &amp; Praktik Budidaya
</div>
<div>
<span class="badge bg-label-primary">D2</span> Sosial Ekonomi Rumah Tangga
</div>
<div>
<span class="badge bg-label-primary">D3</span> Rantai Nilai &amp; Akses Pasar
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-6 col-sm-12">
<div class="card h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<div class="card-title mb-0">
<h5 class="m-0 me-2">Rata-rata Komponen Kesiapan Adopsi</h5>
<p class="card-subtitle">untuk semua komoditas</p>
</div>
</div>
<div class="card-body">
<div id="chart-komponen"></div>
<div class="d-flex flex-wrap gap-3 mt-3 small justify-content-center">
<div>
<span class="badge bg-label-primary">K1</span> Motivasi &amp; Kapasitas Adopsi
</div>
<div>
<span class="badge bg-label-primary">K2</span> Kondisi Ekonomi Rumah Tangga
</div>
<div>
<span class="badge bg-label-primary">K3</span> Praktik Budidaya &amp; GAP
</div>
<div>
<span class="badge bg-label-primary">K4</span> Keterlibatan Kelembagaan
</div>
<div>
<span class="badge bg-label-primary">K5</span> Akses &amp; Kebebasan Keuangan
</div>
<div>
<span class="badge bg-label-primary">K6</span> Rantai Nilai &amp; Akses Pasar
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
@push('scripts')
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<script>
$('.data-table').DataTable({
"paging": false,
"lengthChange": true,
"searching": false,
"ordering": false,
"info": false,
"autoWidth": false,
"responsive": false,
"scrollX": true
});
// Chart Segmentasi Petani
var optionsSegmentasiPetani = {
series: @json($seriesSegmentasi),
chart: {
type: 'donut',
width: 320,
},
labels: @json(array_column($segments, 'name')),
colors: @json($colors),
plotOptions: {
pie: {
borderRadius: 12,
spacing: 5,
donut: {
size: '68%',
labels: {
show: true,
total: {
show: true,
label: 'Petani Tersegmentasi',
},
},
},
},
},
stroke: {
width: 0,
},
dataLabels: {
enabled: false,
},
legend: {
show: false,
},
responsive: [
{
breakpoint: 480,
options: {
chart: {
width: 240,
},
},
},
],
}
var chartSegmentasiPetani = new ApexCharts(document.querySelector('#chart-segmentasi-petani'), optionsSegmentasiPetani)
chartSegmentasiPetani.render()
// Chart Segmentasi Petani By Komoditas
var optionsSegmentasiPetaniByKomoditas = {
series: @json($seriesSegmentasiKomoditas),
colors: @json($colors),
chart: {
type: 'bar',
height: 240,
stacked: true,
},
plotOptions: {
bar: {
horizontal: true,
},
},
stroke: {
width: 1,
colors: ['#fff'],
},
title: {
show: false,
},
xaxis: {
categories: @json($komoditas->pluck('nama')),
},
tooltip: {
y: {
formatter: function (val) {
return val + ' petani'
},
},
},
fill: {
opacity: 1,
},
legend: {
position: 'top',
horizontalAlign: 'left',
offsetX: 40,
},
}
// Chart Segmentasi Petani By Komoditas
var chartSegmentasiPetaniByKomoditas = new ApexCharts(document.querySelector('#chart-segmentasi-petani-komoditas'), optionsSegmentasiPetaniByKomoditas)
chartSegmentasiPetaniByKomoditas.render()
// Chart Dimensi dan Komponen Kesiapan Adopsi
let cardColor, labelColor, fontFamily, headingColor, shadeColor, legendColor, borderColor, barBgColor;
if (isDarkStyle) {
barBgColor = '#3d4157';
shadeColor = 'dark';
} else {
barBgColor = '#efeef0';
shadeColor = '';
}
cardColor = config.colors.cardColor;
labelColor = config.colors.textMuted;
legendColor = config.colors.bodyColor;
borderColor = config.colors.borderColor;
headingColor = config.colors.headingColor;
var radarDimensi = new ApexCharts($("#chart-dimensi")[0],
options = {
chart: {
height: 340,
type: 'radar',
toolbar: {
show: false
}
},
series: [
{
name: "Rata-rata Dimensi Kesiapan Adopsi",
data: [{{ round($avgDimensi->skor_d2_sistem_praktik_budidaya, 2) }},
{{ round($avgDimensi->skor_d4_sosial_ekonomi, 2) }},
{{ round($avgDimensi->skor_d6_rantai_nilai_akses_pasar, 2) }}]
}
],
labels: ['Sistem & Praktik Budidaya', 'Sosial Ekonomi Rumah Tangga', 'Rantai Nilai & Akses Pasar'],
plotOptions: {
radar: {
polygons: {
strokeColors: borderColor,
connectorColors: borderColor
}
}
},
stroke: {
width: 2
},
legend: {
show: true,
fontSize: '13px',
position: 'bottom',
labels: {
colors: legendColor,
useSeriesColors: false
},
markers: {
height: 12,
width: 12
},
itemMargin: {
horizontal: 10
},
onItemHover: {
highlightDataSeries: false
}
},
colors: [config.colors.primary, config.colors.info],
fill: {
opacity: 0.85
},
markers: {
show: true,
width: 1,
},
grid: {
show: false,
padding: {
top: -25,
bottom: -5
}
},
xaxis: {
categories: ['D1', 'D2', 'D3'],
labels: {
show: true,
style: {
colors: [labelColor, labelColor, labelColor, labelColor, labelColor, labelColor],
fontSize: '13px',
fontFamily: fontFamily
}
}
},
yaxis: {
show: true,
min: 0,
max: 5,
tickAmount: 5
},
responsive: [
{
breakpoint: 769,
options: {
chart: {
height: 400
}
}
}
]
});
radarDimensi.render();
var radarKomponen = new ApexCharts($("#chart-komponen")[0],
options = {
chart: {
height: 340,
type: 'radar',
toolbar: {
show: false
}
},
series: [
{
name: "Rata-rata Komponen Kesiapan Adopsi",
data: [
{{ round($avgKomponen->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi, 2) }},
{{ round($avgKomponen->skor_komp_2_d4_k2_ekonomi_rumah_tangga, 2) }},
{{ round($avgKomponen->skor_komp_3_d2_praktik_budidaya_gap, 2) }},
{{ round($avgKomponen->skor_komp_4_d4_k4_keterlibatan_kelembagaan, 2) }},
{{ round($avgKomponen->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan, 2) }},
{{ round($avgKomponen->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar, 2) }}
]
}
],
lotOptions: {
radar: {
polygons: {
strokeColors: borderColor,
connectorColors: borderColor
}
}
},
stroke: {
width: 2
},
legend: {
show: true,
fontSize: '13px',
position: 'bottom',
labels: {
colors: legendColor,
useSeriesColors: false
},
markers: {
height: 12,
width: 12
},
itemMargin: {
horizontal: 10
},
onItemHover: {
highlightDataSeries: false
}
},
colors: [config.colors.primary, config.colors.info],
fill: {
opacity: 0.85
},
markers: {
show: true,
width: 1,
},
grid: {
show: false,
padding: {
top: -25,
bottom: -5
}
},
xaxis: {
categories: ['K1', 'K2', 'K3', 'K4', 'K5', 'K6'],
labels: {
show: true,
style: {
colors: [labelColor, labelColor, labelColor, labelColor, labelColor, labelColor],
fontSize: '13px',
fontFamily: fontFamily
}
}
},
yaxis: {
show: true,
min: 0,
max: 5,
tickAmount: 5
},
responsive: [
{
breakpoint: 769,
options: {
chart: {
height: 400
}
}
}
]
});
radarKomponen.render();
</script>
@endpush
+207 -222
View File
@@ -1,6 +1,35 @@
@extends('layout.main')
@section('content')
@php
$totalPetani = $petaniSummary->sum('total');
$segments = [
[
'name' => 'Penggerak',
'range' => '4.0 - 5.0',
'icon' => 'tabler-crown',
'color' => 'success',
],
[
'name' => 'Perintis',
'range' => '3.0 - 3.9',
'icon' => 'tabler-flag',
'color' => 'info',
],
[
'name' => 'Pemerhati',
'range' => '2.0 - 2.9',
'icon' => 'tabler-eye',
'color' => 'warning',
],
[
'name' => 'Pemula',
'range' => '1.0 - 1.9',
'icon' => 'tabler-seedling',
'color' => 'danger',
],
];
@endphp
<div class="container-xxl flex-grow-1 container-p-y">
<div class="row g-6">
<div class="col-lg-3 col-sm-6">
@@ -12,9 +41,9 @@
<i class="icon-base ti tabler-user-check icon-28px"></i>
</span>
</div>
<h4 class="mb-0">{{ $petaniSummary->sum('total') }}</h4>
<h4 class="mb-0">{{ $totalPetani }}</h4>
</div>
<p class="mb-1">Petani</p>
<p class="mb-1">Total Petani</p>
<p class="mb-0">
<span class="text-heading fw-medium me-2">{{ $petaniSummary->count('total') }}</span>
<small class="text-body-secondary">komoditas utama</small>
@@ -41,29 +70,6 @@
</div>
</div>
</div>
<!-- <div class="col-lg-6 col-sm-12">
<div class="card card-border-shadow-danger h-100">
<div class="card-body">
<div class="d-flex align-items-center mb-2">
<div class="avatar me-4">
<span class="avatar-initial rounded bg-label-danger">
<i class="icon-base ti tabler-seedling icon-28px"></i>
</span>
</div>
<h4 class="mb-0">{{ $tanamanSummary->sum('total') }}</h4>
</div>
<p class="mb-1">Tanaman Komoditas Utama</p>
<div class="d-flex justify-content-between mb-2">
@foreach($komoditas as $k)
<p class="mb-0">
<span class="text-heading fw-medium me-2">{{ $tanamanSummary->where('komoditas_id', $k->id)->sum('total') }}</span>
<small class="text-body-danger">tanaman {{ $k->nama }}</small>
</p>
@endforeach
</div>
</div>
</div>
</div> -->
<div class="col-lg-3 col-sm-6">
<div class="card card-border-shadow-info h-100">
<div class="card-body">
@@ -78,7 +84,6 @@
<p class="mb-1">Rata-rata Indeks Kesiapan Adopsi</p>
<p class="mb-0">
<span class="text-heading fw-medium me-2">{{ $segmenAverage }}</span>
<small class="text-body-info">komoditas utama</small>
</p>
</div>
</div>
@@ -95,146 +100,92 @@
</div>
</div>
<div class="card-body">
<table class="table card-table table-border-top-0 table-border-bottom-0">
<table class="table card-table table-border-top-0 table-border-bottom-0 data-table">
<thead>
<tr>
<th></th>
<th class="text-end pe-0">Petani</th>
<th class="text-end pe-0">%</th>
</tr>
</thead>
<tbody>
@foreach ($segments as $segment)
@php
$total = $skorSummary->where('segmen', $segment['name'])->sum('total');
$persen = $totalPetani ? ($total / $totalPetani) * 100 : 0;
@endphp
<tr>
<td class="w-60 ps-0"></td>
<td class="text-end pe-0">Petani</td>
<td class="text-end pe-0">%</td>
</tr>
<tr>
<td class="w-60 ps-0">
<td>
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-crown icon-lg text-heading"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-success">Penggerak (4.0 - 5.0)</h6>
<!-- <small class="text-body-secondary text-wrap">Siap menjadi peserta agrolab utama dan panutan bagi petani lain</small> -->
<i class="icon-base ti {{ $segment['icon'] }} icon-lg text-{{ $segment['color'] }}"></i>
</div>
<span class="text-{{ $segment['color'] }}">
{{ $segment['name'] }}
<small class="text-body-secondary">({{ $segment['range'] }})</small>
</span>
</div>
</td>
<td class="text-end pe-0">
<span>{{ $skorSummary->where('segmen', 'Penggerak')->sum('total') }} petani</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format(($skorSummary->where('segmen', 'Penggerak')->sum('total') / $petaniSummary->sum('total')) * 100, 2) }}%</span>
</td>
</tr>
<tr>
<td class="w-60 ps-0">
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-flag icon-lg text-heading"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-info">Perintis (3.0 - 3.9)</h6>
<!-- <small class="text-body-secondary text-wrap">Berpotensi berkembang menjadi Penggerak dengan dukungan yang tepat</small> -->
</div>
</div>
</td>
<td class="text-end pe-0">
<span>{{ $skorSummary->where('segmen', 'Perintis')->sum('total') }} petani</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format(($skorSummary->where('segmen', 'Perintis')->sum('total') / $petaniSummary->sum('total')) * 100, 2) }}%</span>
</td>
</tr>
<tr>
<td class="w-60 ps-0">
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-eye icon-lg text-heading text-success"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-warning">Pemerhati (2.0 - 2.9)</h6>
<!-- <small class="text-body-secondary text-wrap">Perlu melihat bukti hasil nyata dari Penggerak sebelum mau bergerak</small> -->
</div>
</div>
</td>
<td class="text-end pe-0">
<span>{{ $skorSummary->where('segmen', 'Pemerhati')->sum('total') }} petani</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format(($skorSummary->where('segmen', 'Pemerhati')->sum('total') / $petaniSummary->sum('total')) * 100, 2) }}%</span>
</td>
</tr>
<tr>
<td class="w-60 ps-0">
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-seedling icon-lg text-heading"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-danger">Pemula (1.0 - 1.9)</h6>
<!-- <small class="text-body-secondary text-wrap">Butuh penanganan hambatan dasar terlebih dahulu sebelum intervensi langsung</small> -->
</div>
</div>
</td>
<td class="text-end pe-0">
<span>{{ $skorSummary->where('segmen', 'Pemula')->sum('total') }} petani</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format(($skorSummary->where('segmen', 'Pemula')->sum('total') / $petaniSummary->sum('total')) * 100, 2) }}%</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- <div class="col-lg-6 col-sm-12">
<div class="card h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<div class="card-title mb-0">
<h5 class="m-0 me-2">Segmentasi Petani Komoditas</h5>
<p class="card-subtitle">berdasarkan mayoritas segmentasi</p>
</div>
</div>
<div class="card-body">
<table class="table card-table table-border-top-0 table-border-bottom-0">
<tbody>
@foreach ($komoditas as $k)
<?php
$max = $skorKomoditasSummary->where('komoditas_id', $k->id)
->whereIn('segmen', ['Penggerak', 'Perintis', 'Pemerhati', 'Pemula'])
->sortByDesc('total')
->first();
?>
<tr>
<td class="w-40 ps-0">
<h6 class="mb-0 fw-normal text-heading">{{ $k->nama }}</h6>
</td>
<td class="pe-0">
@if(isset($max))
@if($max->segmen == 'Penggerak')
<span class="text-success">Petani Penggerak</span>
@elseif($max->segmen == 'Perintis')
<span class="text-info">Petani Perintis</span>
@elseif($max->segmen == 'Pemerhati')
<span class="text-warning">Petani Pemerhati</span>
@elseif($max->segmen == 'Pemula')
<span class="text-danger">Petani Pemula</span>
@else
<span>Belum Lengkap</span>
@endif
@else
<span>Belum Tersegmentasi</span>
@endif
</td>
<td class="text-end pe-0">
<span>{{ isset($max) ? $max->total : 0 }} Petani</span>
</td>
<td class="text-end pe-0">
<span>{{ isset($max) ? number_format(($max->total / $petaniSummary->sum('total')) * 100, 2) : 0 }}%</span>
</td>
<td class="text-end pe-0">{{ number_format($total) }}</td>
<td class="text-end pe-0">{{ number_format($persen, 2) }}%</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div> -->
</div>
<div class="col-lg-6 col-sm-12">
<div class="card h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<div class="card-title mb-0">
<h5 class="m-0 me-2">Segmentasi Petani</h5>
<p class="card-subtitle">per komoditas</p>
</div>
</div>
<div class="card-body">
<table class="table card-table table-border-top-0 table-border-bottom-0 data-table">
<thead>
<tr>
<th></th>
@foreach ($komoditas as $k)
<th class="text-end pe-0">{{ $k->nama }}</th>
@endforeach
</tr>
</thead>
<tbody>
@foreach ($segments as $segment)
<tr>
<td>
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti {{ $segment['icon'] }} icon-lg text-{{ $segment['color'] }}"></i>
</div>
<span class="text-{{ $segment['color'] }}">
{{ $segment['name'] }}
<small class="text-body-secondary">({{ $segment['range'] }})</small>
</span>
</div>
</td>
@foreach ($komoditas as $k)
@php
$jumlah = $skorKomoditasSummary->where('segmen', $segment['name'])->where('komoditas_id', $k->id)->sum('total');
@endphp
<td class="text-end pe-0">{{ number_format($jumlah) }}</td>
@endforeach
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="row g-6 py-4">
<div class="col-lg-6 col-sm-12">
<div class="card h-100">
<div class="card-header d-flex justify-content-between align-items-center">
@@ -244,115 +195,124 @@
</div>
</div>
<div class="card-body">
<table class="table card-table table-border-top-0 table-border-bottom-0">
<table class="table card-table table-border-top-0 table-border-bottom-0 data-table">
<thead>
<tr>
<th></th>
<th class="text-end pe-0">Indeks</th>
<th class="text-end pe-0">D1</th>
<th class="text-end pe-0">D2</th>
<th class="text-end pe-0">D3</th>
</tr>
</thead>
<tbody>
@foreach ($segments as $segment)
@php
$skor = $skorMultiDimensi->firstWhere('segmen', $segment['name']);
@endphp
<tr>
<td class="w-60 ps-0"></td>
<td class="text-end pe-0">Indeks</td>
<td class="text-end pe-0">D1</td>
<td class="text-end pe-0">D2</td>
<td class="text-end pe-0">D3</td>
</tr>
<tr>
<td class="w-60 ps-0">
<td>
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-crown icon-lg text-heading"></i>
<i class="icon-base ti {{ $segment['icon'] }} icon-lg text-{{ $segment['color'] }}"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-success">Penggerak (4.0 - 5.0)</h6>
<!-- <small class="text-body-secondary text-wrap">Siap menjadi peserta agrolab utama dan panutan bagi petani lain</small> -->
<h6 class="mb-0 fw-normal text-{{ $segment['color'] }}">
{{ $segment['name'] }}
<small class="text-body-secondary">({{ $segment['range'] }})</small>
</h6>
</div>
</div>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Penggerak')->value('skor_kesiapan_adopsi'), 2, '.', ',') }}</span>
{{ number_format($skor?->skor_kesiapan_adopsi ?? 0, 2, '.', ',') }}
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Penggerak')->value('skor_d2_sistem_praktik_budidaya'), 2, '.', ',') }}</span>
{{ number_format($skor?->skor_d2_sistem_praktik_budidaya ?? 0, 2, '.', ',') }}
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Penggerak')->value('skor_d4_sosial_ekonomi'), 2, '.', ',') }}</span>
{{ number_format($skor?->skor_d4_sosial_ekonomi ?? 0, 2, '.', ',') }}
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Penggerak')->value('skor_d6_rantai_nilai_akses_pasar'), 2, '.', ',') }}</span>
{{ number_format($skor?->skor_d6_rantai_nilai_akses_pasar ?? 0, 2, '.', ',') }}
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
<div class="col-lg-6 col-sm-12">
<div class="card h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<div class="card-title mb-0">
<h5 class="m-0 me-2">Segmentasi Multi Komponen Petani</h5>
<p class="card-subtitle">untuk semua komoditas</p>
</div>
</div>
<div class="card-body">
<table class="table card-table table-border-top-0 table-border-bottom-0 data-table">
<thead>
<tr>
<td class="w-60 ps-0">
<th></th>
<th class="text-end pe-0">Indeks</th>
<th class="text-end pe-0">K1</th>
<th class="text-end pe-0">K2</th>
<th class="text-end pe-0">K3</th>
<th class="text-end pe-0">K4</th>
<th class="text-end pe-0">K5</th>
<th class="text-end pe-0">K6</th>
</tr>
</thead>
<tbody>
@foreach ($segments as $segment)
@php
$skor = $skorMultiKomponen->firstWhere('segmen', $segment['name']);
@endphp
<tr>
<td class="">
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-flag icon-lg text-heading"></i>
<i class="icon-base ti {{ $segment['icon'] }} icon-lg text-{{ $segment['color'] }}"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-info">Perintis (3.0 - 3.9)</h6>
<!-- <small class="text-body-secondary text-wrap">Berpotensi berkembang menjadi Penggerak dengan dukungan yang tepat</small> -->
<h6 class="mb-0 fw-normal text-{{ $segment['color'] }}">
{{ $segment['name'] }}
<small class="text-body-secondary">({{ $segment['range'] }})</small>
</h6>
</div>
</div>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Perintis')->value('skor_kesiapan_adopsi'), 2, '.', ',') }}</span>
<span>{{ number_format($skor?->skor_kesiapan_adopsi, 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Perintis')->value('skor_d2_sistem_praktik_budidaya'), 2, '.', ',') }}</span>
<span>{{ number_format($skor?->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi, 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Perintis')->value('skor_d4_sosial_ekonomi'), 2, '.', ',') }}</span>
<span>{{ number_format($skor?->skor_komp_2_d4_k2_ekonomi_rumah_tangga, 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Perintis')->value('skor_d6_rantai_nilai_akses_pasar'), 2, '.', ',') }}</span>
<span>{{ number_format($skor?->skor_komp_3_d2_praktik_budidaya_gap, 2, '.', ',') }}</span>
</td>
</tr>
<tr>
<td class="w-60 ps-0">
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-eye icon-lg text-heading text-success"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-warning">Pemerhati (2.0 - 2.9)</h6>
<!-- <small class="text-body-secondary text-wrap">Perlu melihat bukti hasil nyata dari Penggerak sebelum mau bergerak</small> -->
</div>
</div>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemerhati')->value('skor_kesiapan_adopsi'), 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemerhati')->value('skor_d2_sistem_praktik_budidaya'), 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemerhati')->value('skor_d4_sosial_ekonomi'), 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemerhati')->value('skor_d6_rantai_nilai_akses_pasar'), 2, '.', ',') }}</span>
</td>
</tr>
<tr>
<td class="w-60 ps-0">
<div class="d-flex justify-content-start align-items-center">
<div class="me-2">
<i class="icon-base ti tabler-seedling icon-lg text-heading"></i>
</div>
<div>
<h6 class="mb-0 fw-normal text-danger">Pemula (1.0 - 1.9)</h6>
<!-- <small class="text-body-secondary text-wrap">Butuh penanganan hambatan dasar terlebih dahulu sebelum intervensi langsung</small> -->
</div>
</div>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemula')->value('skor_kesiapan_adopsi'), 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemula')->value('skor_d2_sistem_praktik_budidaya'), 2, '.', ',') }}</span>
<span>{{ number_format($skor?->skor_komp_4_d4_k4_keterlibatan_kelembagaan, 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemula')->value('skor_d4_sosial_ekonomi'), 2, '.', ',') }}</span>
<span>{{ number_format($skor?->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan, 2, '.', ',') }}</span>
</td>
<td class="text-end pe-0">
<span>{{ number_format($skorMultiDimensi->where('segmen', 'Pemula')->value('skor_d6_rantai_nilai_akses_pasar'), 2, '.', ',') }}</span>
<span>{{ number_format($skor?->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar, 2, '.', ',') }}</span>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@@ -443,6 +403,13 @@
<th>D2</th>
<th>D4</th>
<th>D6</th>
<th>K1</th>
<th>K2</th>
<th>K3</th>
<th>K4</th>
<th>K5</th>
<th>K6</th>
</tr>
</thead>
<tbody>
@foreach ($petani as $item)
@@ -466,6 +433,12 @@
<td>{{ number_format($item->skor?->skor_d2_sistem_praktik_budidaya, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_d4_sosial_ekonomi, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_d6_rantai_nilai_akses_pasar, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_komp_2_d4_k2_ekonomi_rumah_tangga, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_komp_3_d2_praktik_budidaya_gap, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_komp_4_d4_k4_keterlibatan_kelembagaan, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan, 2, '.', ',') }}</td>
<td>{{ number_format($item->skor?->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar, 2, '.', ',') }}</td>
</tr>
@endforeach
</tbody>
@@ -484,6 +457,17 @@
<script>
$(document).ready(function() {
$('.data-table').DataTable({
"paging": false,
"lengthChange": true,
"searching": false,
"ordering": false,
"info": false,
"autoWidth": false,
"responsive": false,
"scrollX": true
});
$("#tabel-petani").DataTable({
"paging": true,
"lengthChange": true,
@@ -491,7 +475,8 @@
"ordering": false,
"info": true,
"autoWidth": false,
"responsive": true,
"responsive": false,
"scrollX": true
})
+49
View File
@@ -3,6 +3,7 @@
<a href="{{ route('home') }}" class="app-brand-link">
<span class="app-brand-logo demo">
<span>
<!-- AgroMonev -->
<svg width="32" height="24" viewBox="0 0 32 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.3" d="M16 2.5C16 2.5 5 6.5 5 15.5C5 20.5 11 23.5 16 23.5V2.5Z" fill="#28a745" />
<path opacity="0.6" d="M16 2.5C16 2.5 27 6.5 27 15.5C27 20.5 21 23.5 16 23.5V2.5Z" fill="#28a745" />
@@ -10,6 +11,24 @@
<path d="M15 15L27 4" stroke="#ED1C24" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" />
<circle cx="27" cy="4" r="2.5" fill="#ED1C24" />
</svg>
<!-- AgroPro -->
<!-- <svg width="32" height="24" viewBox="0 0 32 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.25" d="M16 2.5C16 2.5 5 6.5 5 15.5C5 20.5 11 23.5 16 23.5V2.5Z" fill="#28A745"/>
<path opacity="0.5" d="M16 2.5C16 2.5 27 6.5 27 15.5C27 20.5 21 23.5 16 23.5V2.5Z" fill="#28A745"/>
<rect x="5.5" y="5.5" width="21" height="15" rx="2.5" fill="white" stroke="#0054A6" stroke-width="1.5"/>
<rect x="11" y="3.5" width="10" height="4" rx="2" fill="#0054A6"/>
<circle cx="9.5" cy="10" r="1.7" fill="#28A745"/>
<path d="M8.7 10L9.3 10.6L10.4 9.3" stroke="white" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13 10H23" stroke="#D9E2EC" stroke-width="2" stroke-linecap="round"/>
<path d="M13 10H22" stroke="#0054A6" stroke-width="2" stroke-linecap="round"/>
<circle cx="9.5" cy="14" r="1.7" fill="#28A745"/>
<path d="M8.7 14L9.3 14.6L10.4 13.3" stroke="white" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13 14H23" stroke="#D9E2EC" stroke-width="2" stroke-linecap="round"/>
<path d="M13 14H19.5" stroke="#F4B400" stroke-width="2" stroke-linecap="round"/>
<circle cx="9.5" cy="18" r="1.7" fill="white" stroke="#ED1C24" stroke-width="1.3"/>
<path d="M13 18H23" stroke="#D9E2EC" stroke-width="2" stroke-linecap="round"/>
<path d="M13 18H17" stroke="#ED1C24" stroke-width="2" stroke-linecap="round"/>
</svg> -->
</span>
</span>
@@ -49,6 +68,16 @@
</ul>
@endif
@if(in_array($userRole, ['super_admin', 'admin']) && env('APP_NAME') == 'AgroMonev')
<ul class="menu-sub">
<li class="menu-item {{ request()->routeIs('dashboard.demografi-petani') ? 'active' : '' }}">
<a href="{{ route('dashboard.demografi-petani') }}" class="menu-link">
<div data-i18n="Demografi Petani">Demografi Petani</div>
</a>
</li>
</ul>
@endif
@if(in_array($userRole, ['super_admin', 'admin', 'fasilitator']) && env('APP_NAME') == 'AgroMonev')
<ul class="menu-sub">
<li class="menu-item {{ request()->routeIs('dashboard.survey-petani') ? 'active' : '' }}">
@@ -65,6 +94,15 @@
</li>
</ul>
@endif
@if(in_array($userRole, ['super_admin', 'admin']) && env('APP_NAME') == 'AgroMonev')
<ul class="menu-sub">
<li class="menu-item {{ request()->routeIs('dashboard.bumdes') ? 'active' : '' }}">
<a href="{{ route('dashboard.bumdes') }}" class="menu-link">
<div data-i18n="Profil Pengurus BUMDes">Profil Pengurus BUMDes</div>
</a>
</li>
</ul>
@endif
</li>
@endif
@@ -79,6 +117,17 @@
</a>
</li>
@endif
@if(in_array($userRole, ['super_admin', 'admin']) && env('APP_NAME') == 'AgroMonev')
<li class="menu-header small">
<span class="menu-header-text" data-i18n="Data BUMDes">Data BUMDes</span>
</li>
<li class="menu-item {{ request()->routeIs('bumdes.*') ? 'active' : '' }}">
<a href="{{ route('bumdes.index') }}" class="menu-link">
<i class="menu-icon icon-base ti tabler-file-description"></i>
<div data-i18n="Profil Pengurus BUMDes">Profil Pengurus BUMDes</div>
</a>
</li>
@endif
@if(in_array($userRole, ['super_admin', 'admin']) && env('APP_NAME') == 'AgroPro')
<!-- Ekosistem -->
@@ -15,8 +15,8 @@
<div class="w-25">
<x-summary-card
title="Lahan & Tanaman"
count="{{ number_format(($lahan?->sum('luas_lahan') ?? 0) / 10000, 2, ',', '.') }} ha"
subtitle="{{ $tanaman?->count() }} tanaman dari {{ $komoditas?->count() }} komoditas utama"
count="{{ number_format(($totalLuasLahan ?? 0) / 10000, 2, ',', '.') }} ha"
subtitle="{{ $totalTanaman ?? 0 }} tanaman dari {{ $komoditas?->count() }} komoditas utama"
icon="trees"
color="success"
/>
@@ -1598,42 +1598,66 @@
action="{{ route('petani.survey-produktivitas.store', $petani->id) }}"
class="form-repeater">
@csrf
<input type="hidden" name="redirect_fragment" value="section-kehilangan-hasil">
<input type="hidden" name="redirect_fragment" value="section-produktivitas">
@php
$produktivitasRows = old('produktivitas_komoditas');
if (!is_array($produktivitasRows) || count($produktivitasRows) === 0) {
$produktivitasRows = [
[
'komoditas_id' => null,
'hasil_panen_3_musim' => null,
'satuan' => null,
],
];
}
@endphp
<div data-repeater-list="produktivitas_komoditas">
@foreach ($produktivitasRows as $index => $produktivitasRow)
<div data-repeater-item>
<div class="row align-items-end">
<div class="col-md-4 mb-3">
<label class="form-label">Komoditas</label>
<select name="komoditas_id" class="form-select">
<select name="komoditas_id" class="form-select @error('produktivitas_komoditas.' . $index . '.komoditas_id') is-invalid @enderror">
<option value="">Pilih Komoditas</option>
@foreach ($komoditas as $item)
<option value="{{ $item->id }}">{{ $item->nama }}</option>
<option value="{{ $item->id }}" @selected((string) data_get($produktivitasRow, 'komoditas_id') === (string) $item->id)>{{ $item->nama }}</option>
@endforeach
</select>
@error('produktivitas_komoditas.' . $index . '.komoditas_id')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="col-md-3 mb-3">
<label class="form-label">Hasil</label>
<div class="input-group">
<input type="number" name="hasil_panen_3_musim" class="form-control" step="0.01" min="0">
<input type="number" name="hasil_panen_3_musim" class="form-control @error('produktivitas_komoditas.' . $index . '.hasil_panen_3_musim') is-invalid @enderror" step="0.01" min="0" value="{{ data_get($produktivitasRow, 'hasil_panen_3_musim') }}">
<span class="input-group-text">Kg</span>
</div>
@error('produktivitas_komoditas.' . $index . '.hasil_panen_3_musim')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="col-md-3 mb-3">
<label class="form-label d-block">Satuan</label>
<label class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="satuan" value="ha_tahun">
<input class="form-check-input @error('produktivitas_komoditas.' . $index . '.satuan') is-invalid @enderror" type="radio" name="satuan" value="ha_tahun" @checked(data_get($produktivitasRow, 'satuan') === 'ha_tahun')>
<span class="form-check-label">Ha/Tahun</span>
</label>
<label class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="satuan" value="pohon_tahun">
<input class="form-check-input @error('produktivitas_komoditas.' . $index . '.satuan') is-invalid @enderror" type="radio" name="satuan" value="pohon_tahun" @checked(data_get($produktivitasRow, 'satuan') === 'pohon_tahun')>
<span class="form-check-label">Pohon/Tahun</span>
</label>
@error('produktivitas_komoditas.' . $index . '.satuan')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="col-md-2 mb-3">
@@ -1645,6 +1669,7 @@
</div>
<hr>
</div>
@endforeach
</div>
<div class="mt-4 d-flex justify-content-between">
+7
View File
@@ -45,7 +45,10 @@ Route::middleware('auth')
// Dashboard
Route::get('/dashboard/petani', [App\Http\Controllers\Web\Dashboard\ProfilPetaniController::class, 'index'])->name('dashboard.petani');
Route::get('/dashboard/bumdes', [App\Http\Controllers\Web\Bumdes\PengurusBumdesController::class, 'index'])->name('dashboard.bumdes');
Route::get('/dashboard/petani/demografi', [App\Http\Controllers\Web\Dashboard\DemografiPetaniController::class, 'index'])->name('dashboard.demografi-petani');
Route::get('/dashboard/indeks-petani', [App\Http\Controllers\Web\Dashboard\IndeksPetaniController::class, 'index'])->name('dashboard.indeks-petani');
Route::get('/user-profile', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'index'])->name('userProfile.index');
Route::get('/user-profile/security', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'security'])->name('userProfile.security');
@@ -223,4 +226,8 @@ Route::middleware('auth')
Route::resource('petani.akses-pasar', App\Http\Controllers\Web\Produktivitas\AksesPasarController::class)->whereNumber('petani');
Route::resource('petani.skor', App\Http\Controllers\Web\Produktivitas\SkorPetaniController::class)->only(['index']);
// BUMDes
Route::get('bumdes/{bumdes}/kelembagaan-aktor', [App\Http\Controllers\Web\Bumdes\PengurusBumdesController::class, 'kelembagaanAktor'])->name('bumdes.kelembagaan-aktor.index');
Route::resource('bumdes', App\Http\Controllers\Web\Bumdes\PengurusBumdesController::class);
});