diff --git a/AISTANDAR.md b/AISTANDAR.md index 7a8e76f..a66e1cd 100644 --- a/AISTANDAR.md +++ b/AISTANDAR.md @@ -681,7 +681,7 @@ Status: `Belum` / `Proses` / `Selesai` / `Dikecualikan` | Produktivitas | Tanaman | B | Belum | | | Produktivitas | MapTanaman | ? | Belum | | | Produktivitas | Produksi | B | Belum | | -| Produktivitas | Survey Kelompok Tani (+ tab) | C | Belum | | +| Produktivitas | Survey Kelompok Tani (+ tab) | C | Proses | Daftar: Form Request filter, service query, dan JS terpisah; ringkasan profil disiapkan service; form/tab lama belum direfaktor | | Produktivitas | Sebaran Petani | ? | Belum | Sedang dikerjakan, konfirmasi dulu | | Program | Program, Program Komoditas, Program Lokasi | B | Belum | Pindah dari root ke `Program/` | | Program | Framework → Transformasi → Aktivitas → Target | B | Belum | Nested shallow | diff --git a/app/Enums/JenisKelompokTani.php b/app/Enums/JenisKelompokTani.php new file mode 100644 index 0000000..9310b1f --- /dev/null +++ b/app/Enums/JenisKelompokTani.php @@ -0,0 +1,18 @@ +mapWithKeys(fn (self $jenis) => [$jenis->value => $jenis->value])->all(); + } +} diff --git a/app/Enums/StatusLegalitasKelompokTani.php b/app/Enums/StatusLegalitasKelompokTani.php new file mode 100644 index 0000000..60673d9 --- /dev/null +++ b/app/Enums/StatusLegalitasKelompokTani.php @@ -0,0 +1,17 @@ +mapWithKeys(fn (self $status) => [$status->value => $status->value])->all(); + } +} diff --git a/app/Http/Controllers/Web/Produktivitas/SurveyKelompokTaniController.php b/app/Http/Controllers/Web/Produktivitas/SurveyKelompokTaniController.php index bd939e6..af6c81c 100644 --- a/app/Http/Controllers/Web/Produktivitas/SurveyKelompokTaniController.php +++ b/app/Http/Controllers/Web/Produktivitas/SurveyKelompokTaniController.php @@ -3,6 +3,9 @@ namespace App\Http\Controllers\Web\Produktivitas; use App\Http\Controllers\Controller; +use App\Http\Requests\Produktivitas\IndexKelompokTaniRequest; +use App\Services\Produktivitas\KelompokTaniService; +use Illuminate\View\View; use Illuminate\Http\Request; use Illuminate\Support\Facades\Gate; use Illuminate\Support\Str; @@ -32,94 +35,10 @@ class SurveyKelompokTaniController extends Controller ]); } - public function index(Request $request) + public function index(IndexKelompokTaniRequest $request): View { - $validated = $request->validate([ - 'search' => ['nullable', 'string', 'max:255'], - 'kabupaten_kota_id' => ['nullable', 'integer', 'exists:master_kabupaten_kota,id'], - 'kecamatan_id' => ['nullable', 'integer', 'exists:master_kecamatan,id'], - 'desa_kelurahan_id' => ['nullable', 'integer', 'exists:master_desa_kelurahan,id'], - 'komoditas_id' => ['nullable', 'integer', 'exists:master_komoditas,id'], - 'jenis_kelompok' => ['nullable', 'string', 'max:50'], - 'sort_by' => ['nullable', 'string'], - 'per_page' => ['nullable', 'integer', 'in:10,25'], - ]); - - $defaultKabupaten = KabupatenKota::select('id', 'nama') - ->whereRaw('lower(nama) like ?', ['%ngada%'])->orderBy('nama')->first(); - $allowedSorts = ['nama_asc', 'nama_desc', 'anggota_desc', 'anggota_asc']; - $filters = [ - 'search' => $validated['search'] ?? null, - 'kabupaten_kota_id' => $validated['kabupaten_kota_id'] ?? $defaultKabupaten?->id, - 'kecamatan_id' => $validated['kecamatan_id'] ?? null, - 'desa_kelurahan_id' => $validated['desa_kelurahan_id'] ?? null, - 'komoditas_id' => $validated['komoditas_id'] ?? null, - 'jenis_kelompok' => $validated['jenis_kelompok'] ?? null, - 'sort_by' => in_array($validated['sort_by'] ?? null, $allowedSorts, true) - ? $validated['sort_by'] : null, - ]; - - $query = KelompokTani::query() - ->when(filled($filters['search']), function ($query) use ($filters) { - $search = '%' . Str::lower($filters['search']) . '%'; - $query->where(function ($query) use ($search) { - $query->whereRaw('lower(nama_kelompok) like ?', [$search]) - ->orWhereRaw('lower(nama_responden) like ?', [$search]); - }); - }) - ->when($filters['kabupaten_kota_id'], function ($query, $id) { - $query->whereHas('desaKelurahan.kecamatan', fn ($query) => $query->where('kabupaten_kota_id', $id)); - }) - ->when($filters['kecamatan_id'], function ($query, $id) { - $query->whereHas('desaKelurahan', fn ($query) => $query->where('kecamatan_id', $id)); - }) - ->when($filters['desa_kelurahan_id'], fn ($query, $id) => $query->where('desa_kelurahan_id', $id)) - ->when($filters['komoditas_id'], function ($query, $id) { - $query->where(function ($query) use ($id) { - $query->whereJsonContains('komoditas_id', (string) $id) - ->orWhereJsonContains('komoditas_id', (int) $id); - }); - }) - ->when($filters['jenis_kelompok'], fn ($query, $jenis) => $query->where('jenis_kelompok', $jenis)); - - $summary = (clone $query)->selectRaw(' - COUNT(*) AS total_kelompok, - COUNT(DISTINCT jenis_kelompok) AS total_jenis, - COALESCE(SUM(jumlah_pengurus), 0) AS total_pengurus, - COALESCE(SUM(jumlah_pengurus_aktif), 0) AS pengurus_aktif, - COALESCE(SUM(jumlah_anggota_terdaftar), 0) AS total_anggota, - COALESCE(SUM(jumlah_anggota_aktif), 0) AS anggota_aktif - ')->first(); - - match ($filters['sort_by']) { - 'nama_asc' => $query->orderBy('nama_kelompok'), - 'nama_desc' => $query->orderByDesc('nama_kelompok'), - 'anggota_desc' => $query->orderByRaw('COALESCE(jumlah_anggota_terdaftar, 0) DESC'), - 'anggota_asc' => $query->orderByRaw('COALESCE(jumlah_anggota_terdaftar, 0) ASC'), - default => $query->latest(), - }; - - $perPage = (int) ($validated['per_page'] ?? 10); - $kelompokTani = $query->with('desaKelurahan.kecamatan')->orderByDesc('id') - ->paginate($perPage)->appends([...$filters, 'per_page' => $perPage]); - $selectedKabupaten = $filters['kabupaten_kota_id'] - ? KabupatenKota::select('id', 'nama')->find($filters['kabupaten_kota_id']) : null; - $kecamatanOptions = $filters['kabupaten_kota_id'] - ? Kecamatan::select('id', 'nama')->where('kabupaten_kota_id', $filters['kabupaten_kota_id'])->orderBy('nama')->get() - : collect(); - $desaOptions = $filters['kecamatan_id'] - ? DesaKelurahan::select('id', 'nama')->where('kecamatan_id', $filters['kecamatan_id'])->orderBy('nama')->get() - : collect(); - $komoditasOptions = Komoditas::select('id', 'nama')->orderBy('nama')->get(); - $jenisKelompokOptions = KelompokTani::query()->whereNotNull('jenis_kelompok') - ->where('jenis_kelompok', '!=', '')->distinct()->orderBy('jenis_kelompok')->pluck('jenis_kelompok'); - - return view('produktivitas.survey-kelompok-tani.index', compact( - 'kelompokTani', 'summary', 'filters', 'selectedKabupaten', - 'kecamatanOptions', 'desaOptions', 'komoditasOptions', 'jenisKelompokOptions' - )); + return view('produktivitas.survey-kelompok-tani.index', app(KelompokTaniService::class)->indexData($request->validated())); } - public function create() { $this->authorizeAccess(); @@ -129,6 +48,7 @@ class SurveyKelompokTaniController extends Controller return view('produktivitas.survey-kelompok-tani.add', [ ...compact('provinsi', 'komoditas'), + 'ringkasanProfil' => app(KelompokTaniService::class)->profileSummary(), ...$this->profileLocationOptions(), ]); } @@ -178,15 +98,18 @@ class SurveyKelompokTaniController extends Controller public function edit(Request $request, KelompokTani $kelompokTani) { $this->authorizeAccess(); + $ringkasanProfil = app(KelompokTaniService::class)->profileSummary($kelompokTani); return match ($request->query('section', 'identitas')) { - 'kelembagaan' => view('produktivitas.survey-kelompok-tani.kelembagaan', compact('kelompokTani')), + 'kelembagaan' => view('produktivitas.survey-kelompok-tani.kelembagaan', compact('kelompokTani', 'ringkasanProfil')), 'aktivitas-fungsi' => view('produktivitas.survey-kelompok-tani.aktivitas-fungsi', [ 'kelompokTani' => $kelompokTani->loadMissing(['aset', 'bantuan']), + 'ringkasanProfil' => $ringkasanProfil, ]), - 'sosial-konflik' => view('produktivitas.survey-kelompok-tani.sosial-konflik', compact('kelompokTani')), + 'sosial-konflik' => view('produktivitas.survey-kelompok-tani.sosial-konflik', compact('kelompokTani', 'ringkasanProfil')), default => view('produktivitas.survey-kelompok-tani.edit', [ 'kelompokTani' => $kelompokTani->loadMissing('pengurus'), + 'ringkasanProfil' => $ringkasanProfil, 'provinsi' => Provinsi::orderBy('kode', 'asc')->get(), 'komoditas' => Komoditas::where('is_utama', true)->get(), ...$this->profileLocationOptions($kelompokTani), diff --git a/app/Http/Requests/Produktivitas/IndexKelompokTaniRequest.php b/app/Http/Requests/Produktivitas/IndexKelompokTaniRequest.php new file mode 100644 index 0000000..3d1aa31 --- /dev/null +++ b/app/Http/Requests/Produktivitas/IndexKelompokTaniRequest.php @@ -0,0 +1,55 @@ + ['nullable', 'string', 'max:255'], + 'kabupaten_kota_id' => ['bail', 'nullable', 'integer', 'exists:master_kabupaten_kota,id'], + 'kecamatan_id' => ['bail', 'nullable', 'integer', 'exists:master_kecamatan,id'], + 'desa_kelurahan_id' => ['bail', 'nullable', 'integer', 'exists:master_desa_kelurahan,id'], + 'komoditas_id' => ['bail', 'nullable', 'integer', 'exists:master_komoditas,id'], + 'jenis_kelompok' => ['nullable', 'string', 'max:50'], + 'status_legalitas' => ['nullable', 'string', 'max:50'], + 'sort_by' => ['nullable', 'string', 'max:50'], + 'per_page' => ['nullable', 'integer', 'in:10,25'], + ]; + } + + public function messages(): array + { + return [ + 'integer' => ':attribute harus berupa angka bulat.', + 'exists' => ':attribute tidak ditemukan.', + 'string' => ':attribute harus berupa teks.', + 'max' => ':attribute terlalu panjang.', + 'in' => 'Pilihan :attribute tidak valid.', + ]; + } + + public function attributes(): array + { + return [ + 'search' => 'Pencarian', + 'kabupaten_kota_id' => 'Kabupaten/Kota', + 'kecamatan_id' => 'Kecamatan', + 'desa_kelurahan_id' => 'Desa/Kelurahan', + 'komoditas_id' => 'Komoditas', + 'jenis_kelompok' => 'Jenis kelompok', + 'status_legalitas' => 'Status SK/Dokumen Pendaftaran', + 'sort_by' => 'Urutan data', + 'per_page' => 'Jumlah data per halaman', + ]; + } +} diff --git a/app/Models/Pertanian/KelompokTani.php b/app/Models/Pertanian/KelompokTani.php index 60fe059..de0b347 100644 --- a/app/Models/Pertanian/KelompokTani.php +++ b/app/Models/Pertanian/KelompokTani.php @@ -10,6 +10,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use App\Models\Wilayah\DesaKelurahan; +use App\Models\User; class KelompokTani extends Model { @@ -125,6 +126,11 @@ class KelompokTani extends Model return $this->belongsTo(DesaKelurahan::class, 'desa_kelurahan_id'); } + public function creator(): BelongsTo + { + return $this->belongsTo(User::class, 'created_by'); + } + public function pengurus() { return $this->hasMany(PengurusKelompokTani::class, 'survey_kelompok_tani_id'); diff --git a/app/Services/Produktivitas/KelompokTaniService.php b/app/Services/Produktivitas/KelompokTaniService.php new file mode 100644 index 0000000..4eb288f --- /dev/null +++ b/app/Services/Produktivitas/KelompokTaniService.php @@ -0,0 +1,161 @@ +loadMissing('desaKelurahan.kecamatan.kabupatenKota'); + $desa = $kelompokTani?->desaKelurahan; + $statusSk = $kelompokTani?->status_legalitas; + $memilikiSk = in_array($statusSk, KelompokTani::STATUS_LEGALITAS_DENGAN_SK, true); + $komoditas = $kelompokTani?->komoditas_id + ? Komoditas::whereIn('id', $kelompokTani->komoditas_id)->orderBy('nama')->pluck('nama')->unique()->values()->all() + : []; + $tanggalPerubahan = collect([$kelompokTani?->updated_at ?? $kelompokTani?->created_at])->filter(); + if ($kelompokTani?->exists) { + foreach (['pengurus', 'aset', 'bantuan'] as $relation) { + // Penghapusan data bagian juga termasuk pembaruan profil kelompok. + $tanggal = $kelompokTani->{$relation}()->withTrashed()->max(DB::raw('COALESCE(updated_at, created_at)')); + if ($tanggal) { + $tanggalPerubahan->push(Carbon::parse($tanggal)); + } + } + } + + return [ + 'judul' => $kelompokTani ? ($kelompokTani->nama_kelompok ?: 'Profil Kelompok Tani') : 'Profil Kelompok Tani Baru', + 'lokasi' => collect([$desa?->nama, $desa?->kecamatan?->nama, $desa?->kecamatan?->kabupatenKota?->nama]) + ->filter()->implode(' · ') ?: 'Lokasi belum terisi', + 'jenis' => $kelompokTani?->jenis_kelompok ?: 'Belum terisi', + 'legalitas' => [ + 'label' => $memilikiSk ? 'Sudah ada SK' : ($statusSk ?: 'Belum terisi'), + 'detail' => $statusSk ?: 'Belum terisi', + 'warna' => $memilikiSk ? 'success' : 'secondary', + ], + 'pengurus' => $kelompokTani?->jumlah_pengurus !== null ? number_format($kelompokTani->jumlah_pengurus, 0, ',', '.') : 'Belum terisi', + 'anggota' => $kelompokTani?->jumlah_anggota_terdaftar !== null ? number_format($kelompokTani->jumlah_anggota_terdaftar, 0, ',', '.') : 'Belum terisi', + 'komoditas' => $komoditas, + 'responden' => $kelompokTani?->nama_responden ?: 'Belum terisi', + 'jabatan' => $kelompokTani?->jabatan_responden ?: 'Belum terisi', + 'kontak' => $kelompokTani?->kontak_responden ?: 'Belum terisi', + 'tahun_berdiri' => $kelompokTani?->tahun_berdiri ?: 'Belum terisi', + 'diperbarui' => $tanggalPerubahan->sortByDesc(fn ($tanggal) => $tanggal->getTimestamp())->first(), + ]; + } + + public function indexData(array $validated): array + { + $defaultKabupaten = KabupatenKota::select('id', 'nama') + ->whereRaw('lower(nama) like ?', ['%ngada%'])->orderBy('nama')->first(); + $filters = [ + 'search' => $validated['search'] ?? null, + 'kabupaten_kota_id' => $validated['kabupaten_kota_id'] ?? $defaultKabupaten?->id, + 'kecamatan_id' => $validated['kecamatan_id'] ?? null, + 'desa_kelurahan_id' => $validated['desa_kelurahan_id'] ?? null, + 'komoditas_id' => $validated['komoditas_id'] ?? null, + 'jenis_kelompok' => $validated['jenis_kelompok'] ?? null, + 'status_legalitas' => $validated['status_legalitas'] ?? null, + 'sort_by' => in_array($validated['sort_by'] ?? null, ['nama_asc', 'nama_desc', 'anggota_desc', 'anggota_asc'], true) + ? $validated['sort_by'] : null, + ]; + + $query = KelompokTani::query() + ->when(filled($filters['search']), function ($query) use ($filters) { + $search = '%'.Str::lower($filters['search']).'%'; + $query->where(function ($query) use ($search) { + $query->whereRaw('lower(nama_kelompok) like ?', [$search]) + ->orWhereRaw('lower(nama_responden) like ?', [$search]) + ->orWhereHas('desaKelurahan', function ($query) use ($search) { + $query->where(function ($query) use ($search) { + $query->whereRaw('lower(nama) like ?', [$search]) + ->orWhereHas('kecamatan', fn ($query) => $query->whereRaw('lower(nama) like ?', [$search])); + }); + }); + }); + }) + ->when($filters['kabupaten_kota_id'], fn ($query, $id) => $query + ->whereHas('desaKelurahan.kecamatan', fn ($query) => $query->where('kabupaten_kota_id', $id))) + ->when($filters['kecamatan_id'], fn ($query, $id) => $query + ->whereHas('desaKelurahan', fn ($query) => $query->where('kecamatan_id', $id))) + ->when($filters['desa_kelurahan_id'], fn ($query, $id) => $query->where('desa_kelurahan_id', $id)) + ->when($filters['komoditas_id'], fn ($query, $id) => $query->where(function ($query) use ($id) { + $query->whereJsonContains('komoditas_id', (string) $id)->orWhereJsonContains('komoditas_id', (int) $id); + })) + ->when($filters['jenis_kelompok'], function ($query, $value) { + if ($value === JenisKelompokTani::LAINNYA->value) { + $jenisStandar = array_diff(JenisKelompokTani::options(), [JenisKelompokTani::LAINNYA->value]); + $query->whereNotNull('jenis_kelompok')->where('jenis_kelompok', '!=', '')->whereNotIn('jenis_kelompok', $jenisStandar); + } else { + $query->where('jenis_kelompok', $value); + } + }) + ->when($filters['status_legalitas'], fn ($query, $value) => $query->where('status_legalitas', $value)); + + $summary = (clone $query)->selectRaw(' + COUNT(*) AS total_kelompok, + COUNT(DISTINCT desa_kelurahan_id) AS total_desa, + COUNT(DISTINCT jenis_kelompok) AS total_jenis, + COALESCE(SUM(jumlah_pengurus), 0) AS total_pengurus, + COALESCE(SUM(jumlah_pengurus_aktif), 0) AS pengurus_aktif, + COALESCE(SUM(jumlah_anggota_terdaftar), 0) AS total_anggota, + COALESCE(SUM(jumlah_anggota_aktif), 0) AS anggota_aktif + ')->first(); + $summary->memiliki_sk = (clone $query)->whereIn('status_legalitas', KelompokTani::STATUS_LEGALITAS_DENGAN_SK)->count(); + + match ($filters['sort_by']) { + 'nama_asc' => $query->orderBy('nama_kelompok'), + 'nama_desc' => $query->orderByDesc('nama_kelompok'), + 'anggota_desc' => $query->orderByRaw('COALESCE(jumlah_anggota_terdaftar, 0) DESC'), + 'anggota_asc' => $query->orderByRaw('COALESCE(jumlah_anggota_terdaftar, 0) ASC'), + default => $query->latest(), + }; + + $showEnumerator = Gate::any(['super_admin', 'admin']); + $query->with('desaKelurahan.kecamatan'); + if ($showEnumerator) { + $query->with('creator:id,name'); + } + $perPage = (int) ($validated['per_page'] ?? 10); + $kelompokTani = $query->orderByDesc('id')->paginate($perPage)->appends([...$filters, 'per_page' => $perPage]); + $komoditasOptions = Komoditas::select('id', 'nama')->orderBy('nama')->get(); + $komoditasById = $komoditasOptions->keyBy('id'); + $ringkasanKelompok = $kelompokTani->getCollection()->mapWithKeys(function (KelompokTani $item) use ($komoditasById) { + $memilikiSk = in_array($item->status_legalitas, KelompokTani::STATUS_LEGALITAS_DENGAN_SK, true); + + return [$item->id => [ + 'lokasi' => collect([$item->desaKelurahan?->nama, $item->desaKelurahan?->kecamatan?->nama]) + ->filter()->implode(' · ') ?: 'Lokasi belum terisi', + 'komoditas' => collect($item->komoditas_id ?? [])->map(fn ($id) => $komoditasById->get($id)?->nama)->filter()->unique()->values()->all(), + 'legalitas' => [ + 'label' => $memilikiSk ? 'Sudah ada SK' : ($item->status_legalitas ?: 'Belum terisi'), + 'warna' => $memilikiSk ? 'success' : 'secondary', + ], + ]]; + }); + + $selectedKabupaten = $filters['kabupaten_kota_id'] ? KabupatenKota::select('id', 'nama')->find($filters['kabupaten_kota_id']) : null; + $kecamatanOptions = $filters['kabupaten_kota_id'] + ? Kecamatan::select('id', 'nama')->where('kabupaten_kota_id', $filters['kabupaten_kota_id'])->orderBy('nama')->get() : collect(); + $desaOptions = $filters['kecamatan_id'] + ? DesaKelurahan::select('id', 'nama')->where('kecamatan_id', $filters['kecamatan_id'])->orderBy('nama')->get() : collect(); + $jenisKelompokOptions = collect(JenisKelompokTani::options())->values(); + $statusLegalitasOptions = collect(StatusLegalitasKelompokTani::options())->values(); + + return compact('kelompokTani', 'summary', 'filters', 'ringkasanKelompok', 'showEnumerator', 'selectedKabupaten', + 'kecamatanOptions', 'desaOptions', 'komoditasOptions', 'jenisKelompokOptions', 'statusLegalitasOptions'); + } +} diff --git a/public/assets/css/demo.css b/public/assets/css/demo.css index 245295f..f3c8607 100644 --- a/public/assets/css/demo.css +++ b/public/assets/css/demo.css @@ -246,15 +246,6 @@ body > .select2-container--open { border-color: var(--bs-form-invalid-border-color); } -.kelompok-tani-page .kelompok-tani-summary-name { - font-size: .9rem; -} - -.kelompok-tani-page .kelompok-tani-summary-note { - font-size: .75rem; - line-height: 1.3; -} - .kelompok-tani-page .kelompok-tani-help { margin-top: -.75rem; } @@ -400,17 +391,20 @@ body > .select2-container--open { overflow-wrap: anywhere; } -.bumdes-profile-summary .bumdes-summary-content { +.bumdes-profile-summary .bumdes-summary-content, +.kelompok-profile-summary .kelompok-summary-content { min-inline-size: 0; } -.bumdes-profile-summary .bumdes-summary-label { +.bumdes-profile-summary .bumdes-summary-label, +.kelompok-profile-summary .kelompok-summary-label { color: var(--bs-secondary-color); font-size: 0.8125rem; font-weight: 500; } -.bumdes-profile-summary .badge { +.bumdes-profile-summary .badge, +.kelompok-profile-summary .badge { max-inline-size: 100%; line-height: 1.45; white-space: normal; @@ -418,7 +412,56 @@ body > .select2-container--open { overflow-wrap: anywhere; } -.bumdes-profile-summary .bumdes-summary-more { +.bumdes-profile-summary .bumdes-summary-more, +.kelompok-profile-summary .kelompok-summary-more { min-block-size: 1.5rem; font-size: 0.8125rem; } + +/* Daftar kelompok tani. */ +@media (min-width: 768px) { + .kelompok-tani-page .nav-pills-custom-spacing { display: flex; width: 100%; gap: .5rem; flex-wrap: nowrap !important; overflow-x: auto; } + .kelompok-tani-page .nav-pills-custom-spacing::-webkit-scrollbar { display: none; } + .kelompok-tani-page .nav-pills-custom-spacing .nav-item { margin-right: 0 !important; flex: 1; } + .kelompok-tani-page .nav-pills-custom-spacing .nav-link { display: flex; justify-content: center; align-items: center; padding-left: .5rem !important; padding-right: .5rem !important; width: 100%; white-space: nowrap; font-size: var(--bs-body-font-size) !important; } + .kelompok-tani-page .nav-pills-custom-spacing .nav-link i { margin-right: .4rem !important; } +} +.kelompok-tani-row { cursor: pointer; } + .kelompok-filter-row { padding-block: 1.5rem; } + .kelompok-filter-line { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; } + .kelompok-filter-label { display: flex; align-items: center; font-weight: 500; margin-right: .5rem; white-space: nowrap; } + .kelompok-filter-line .form-select, + .kelompok-filter-line .btn { min-height: 31px; } + .kelompok-filter-line .form-select { + background-color: var(--bs-paper-bg); + border-color: var(--bs-border-color); + border-radius: var(--bs-border-radius); + color: var(--bs-body-color); + } + .kelompok-filter-line .form-select:focus { + border-color: rgba(40, 167, 69, .55); + box-shadow: 0 0 0 .2rem rgba(40, 167, 69, .12); + } + .kelompok-filter-line .btn { white-space: nowrap; } + .kelompok-filter-static { + display: flex; align-items: center; min-height: 31px; + padding: .25rem .75rem; font-size: .8125rem; + background-color: var(--bs-paper-bg); + border: 1px solid var(--bs-border-color); + border-radius: var(--bs-border-radius); + color: var(--bs-body-color); + } + .kelompok-filter-line .input-group-sm { width: 240px; } + .kelompok-data-filters > div:not(.kelompok-filter-label) { flex: 1 1 12rem; min-inline-size: 0; } + .kelompok-data-filters .form-select { text-overflow: ellipsis; } + .kelompok-data-filters .input-group-sm { width: 100%; } + .kelompok-list-table .kelompok-list-identity { min-inline-size: 15rem; max-inline-size: 21rem; } + .kelompok-list-table .kelompok-list-commodities { min-inline-size: 10rem; max-inline-size: 15rem; } + .kelompok-list-table .kelompok-list-status { min-inline-size: 10rem; max-inline-size: 15rem; } + @media (max-width: 767.98px) { + .kelompok-filter-line { display: grid; grid-template-columns: minmax(0, 1fr); width: 100%; } + .kelompok-filter-label { margin-right: 0; } + .kelompok-filter-line .btn { justify-content: center; width: 100%; } + .kelompok-filter-line .input-group-sm { width: 100%; } + .kelompok-filter-line .input-group .btn { width: auto; } + } diff --git a/public/assets/js/kelompok-tani.js b/public/assets/js/kelompok-tani.js new file mode 100644 index 0000000..c4be368 --- /dev/null +++ b/public/assets/js/kelompok-tani.js @@ -0,0 +1,66 @@ +'use strict'; + +$(function () { + const filterForm = document.getElementById('kelompok-filter-form'); + if (!filterForm) return; + + const headers = { + 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content, + 'Accept': 'application/json' + }; + const $desa = $('#filter-desa'); + let desaRequest; + + $('#filter-kecamatan').on('change', function () { + if (desaRequest) desaRequest.abort(); + $desa.empty().append(new Option('Semua Desa', '')).prop('disabled', true); + if (!this.value) return; + + desaRequest = $.ajax({ + url: filterForm.dataset.desaUrl.replace(':id', this.value), + method: 'GET', + headers, + success: function (data) { + data.forEach(desa => $desa.append(new Option(desa.nama, desa.id))); + $desa.prop('disabled', false); + }, + error: function (xhr, status) { + if (status !== 'abort') $desa.empty().append(new Option('Gagal memuat desa', '')); + } + }); + }); + + $('#kelompok-per-page').on('change', function () { this.form.submit(); }); + + $(document).on('click', '.kelompok-tani-row', function (event) { + if ($(event.target).closest('a, button, input, select, textarea, label').length) return; + window.location.href = this.querySelector('.edit-record').href; + }); + + $(document).on('click', '.kelompok-tani-page .delete-record', function () { + const url = this.dataset.deleteUrl; + const name = this.dataset.nama; + Swal.fire({ + title: 'Hapus kelompok tani?', + text: `Data kelompok tani "${name}" akan dihapus.`, + icon: 'warning', + showCancelButton: true, + confirmButtonText: 'Ya, hapus', + cancelButtonText: 'Batal', + customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' }, + buttonsStyling: false + }).then(function (result) { + if (!result.isConfirmed) return; + $.ajax({ + url, + method: 'DELETE', + headers, + success: function (response) { + Swal.fire({ icon: 'success', title: 'Terhapus', text: response.message, showConfirmButton: false, timer: 1500 }) + .then(() => window.location.reload()); + }, + error: () => Swal.fire({ icon: 'error', title: 'Gagal menghapus', text: 'Data kelompok tani gagal dihapus. Silakan coba lagi.' }) + }); + }); + }); +}); diff --git a/resources/views/produktivitas/survey-kelompok-tani/add.blade.php b/resources/views/produktivitas/survey-kelompok-tani/add.blade.php index 20ade6c..c24af46 100644 --- a/resources/views/produktivitas/survey-kelompok-tani/add.blade.php +++ b/resources/views/produktivitas/survey-kelompok-tani/add.blade.php @@ -103,12 +103,9 @@ @error('jenis_kelompok')
Jumlah Pengurus & Anggota
-{{ $label }}
-+ {{ $ringkasanProfil['lokasi'] }} +
+Tahun Berdiri: {{ $ringkasanProfil['tahun_berdiri'] }}
Nama Responden
- {{ $kelompokTani->nama_responden ?: '-' }} -Jabatan Responden
- {{ $kelompokTani->jabatan_responden ?: '-' }} -Kontak Responden
- {{ $kelompokTani->kontak_responden ?: '-' }} -Tahun Berdiri
- {{ $kelompokTani->tahun_berdiri ?: '-' }} -Jenis Kelompok
+ {{ $ringkasanProfil['jenis'] }} +Status SK
+ {{ $ringkasanProfil['legalitas']['label'] }} +Komoditas Utama
+ @if(count($ringkasanProfil['komoditas'])) +Belum terisi
+ @endif +Total Pengurus
+ {{ $ringkasanProfil['pengurus'] }} +Total Anggota
+ {{ $ringkasanProfil['anggota'] }} +