Update Profil Detail Petani
This commit is contained in:
@@ -0,0 +1,432 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
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\SkorPetani;
|
||||||
|
use App\Models\Pertanian\Komoditas;
|
||||||
|
use App\Models\Pertanian\Lahan;
|
||||||
|
use App\Models\Pertanian\PendapatanKomoditas;
|
||||||
|
use App\Models\Wilayah\DesaKelurahan;
|
||||||
|
use App\Models\Profile;
|
||||||
|
|
||||||
|
class ProfilPetaniController extends Controller
|
||||||
|
{
|
||||||
|
private const DIMENSION_LOW_MAX = 2.49;
|
||||||
|
private const DIMENSION_MEDIUM_MAX = 3.49;
|
||||||
|
|
||||||
|
public function index(int $id)
|
||||||
|
{
|
||||||
|
$petani = Petani::findOrFail($id);
|
||||||
|
$skorPetani = SkorPetani::where('petani_id', $id)->first();
|
||||||
|
$enumerator = Profile::where('user_id', $petani->created_by)->first();
|
||||||
|
$komoditas = Komoditas::where('id', $petani->komoditas_id)->get();
|
||||||
|
$lahan = Lahan::where('petani_id', $id )->get();
|
||||||
|
|
||||||
|
$desaKelurahan = DesaKelurahan::with('kecamatan')
|
||||||
|
->where('id', $petani->desa_kelurahan_id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$ktpMasked = $petani->ktp ? Str::mask($petani->ktp, '*', 4, -4) : '-';
|
||||||
|
$profiling = $skorPetani ? $this->buildProfiling($skorPetani) : null;
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'petani' => $petani,
|
||||||
|
'skorPetani' => $skorPetani,
|
||||||
|
'enumerator' => $enumerator,
|
||||||
|
'komoditas' => $komoditas,
|
||||||
|
'lahan' => $lahan,
|
||||||
|
'desaKelurahan' => $desaKelurahan,
|
||||||
|
'ktpMasked' => $ktpMasked,
|
||||||
|
'profiling' => $profiling,
|
||||||
|
];
|
||||||
|
return view('produktivitas.profil-petani.index', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildProfiling(SkorPetani $skorPetani): array
|
||||||
|
{
|
||||||
|
$skorAkhir = $this->normalizeScore($skorPetani->skor_kesiapan_adopsi);
|
||||||
|
$segmen = $this->getSegmen($skorAkhir);
|
||||||
|
|
||||||
|
$dimensions = [
|
||||||
|
'd2' => [
|
||||||
|
'kode' => 'D2',
|
||||||
|
'nama' => 'Sistem & Praktik Budidaya',
|
||||||
|
'skor' => $this->normalizeScore(
|
||||||
|
$skorPetani->skor_d2_sistem_praktik_budidaya
|
||||||
|
),
|
||||||
|
],
|
||||||
|
|
||||||
|
'd4' => [
|
||||||
|
'kode' => 'D4',
|
||||||
|
'nama' => 'Sosial-Ekonomi Rumah Tangga',
|
||||||
|
'skor' => $this->normalizeScore(
|
||||||
|
$skorPetani->skor_d4_sosial_ekonomi
|
||||||
|
),
|
||||||
|
],
|
||||||
|
|
||||||
|
'd6' => [
|
||||||
|
'kode' => 'D6',
|
||||||
|
'nama' => 'Rantai Nilai & Akses Pasar',
|
||||||
|
'skor' => $this->normalizeScore(
|
||||||
|
$skorPetani->skor_d6_rantai_nilai_akses_pasar
|
||||||
|
),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($dimensions as $key => $dimension) {
|
||||||
|
$dimensions[$key]['level'] = $this->getDimensionLevel($dimension['skor']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$components = collect([
|
||||||
|
[
|
||||||
|
'key' => 'motivasi',
|
||||||
|
'nama' => 'Motivasi & Kapasitas Adopsi',
|
||||||
|
'short' => 'Motivasi',
|
||||||
|
'dimensi' => 'D4',
|
||||||
|
'bobot' => 25,
|
||||||
|
'icon' => 'tabler-bulb',
|
||||||
|
'skor' => $this->normalizeScore($skorPetani->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi),
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
'key' => 'ekonomi',
|
||||||
|
'nama' => 'Kondisi Ekonomi Rumah Tangga',
|
||||||
|
'short' => 'Ekonomi',
|
||||||
|
'dimensi' => 'D4',
|
||||||
|
'bobot' => 20,
|
||||||
|
'icon' => 'tabler-home-dollar',
|
||||||
|
'skor' => $this->normalizeScore($skorPetani->skor_komp_2_d4_k2_ekonomi_rumah_tangga),
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
'key' => 'gap',
|
||||||
|
'nama' => 'Praktik Budidaya & GAP',
|
||||||
|
'short' => 'Budidaya / GAP',
|
||||||
|
'dimensi' => 'D2',
|
||||||
|
'bobot' => 20,
|
||||||
|
'icon' => 'tabler-plant-2',
|
||||||
|
'skor' => $this->normalizeScore($skorPetani->skor_komp_3_d2_praktik_budidaya_gap),
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
'key' => 'kelembagaan',
|
||||||
|
'nama' => 'Keterlibatan Kelembagaan',
|
||||||
|
'short' => 'Kelembagaan',
|
||||||
|
'dimensi' => 'D4',
|
||||||
|
'bobot' => 15,
|
||||||
|
'icon' => 'tabler-users-group',
|
||||||
|
'skor' => $this->normalizeScore($skorPetani->skor_komp_4_d4_k4_keterlibatan_kelembagaan),
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
'key' => 'keuangan',
|
||||||
|
'nama' => 'Akses & Kebebasan Keuangan',
|
||||||
|
'short' => 'Keuangan',
|
||||||
|
'dimensi' => 'D4',
|
||||||
|
'bobot' => 10,
|
||||||
|
'icon' => 'tabler-building-bank',
|
||||||
|
'skor' => $this->normalizeScore($skorPetani->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan),
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
'key' => 'pasar',
|
||||||
|
'nama' => 'Rantai Nilai & Akses Pasar',
|
||||||
|
'short' => 'Akses Pasar',
|
||||||
|
'dimensi' => 'D6',
|
||||||
|
'bobot' => 10,
|
||||||
|
'icon' => 'tabler-building-store',
|
||||||
|
'skor' => $this->normalizeScore($skorPetani->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$availableComponents = $components
|
||||||
|
->filter(fn ($item) => $item['skor'] !== null)
|
||||||
|
->values();
|
||||||
|
|
||||||
|
$strengths = $availableComponents
|
||||||
|
->sortByDesc('skor')
|
||||||
|
->take(2)
|
||||||
|
->values();
|
||||||
|
|
||||||
|
$barriers = $availableComponents
|
||||||
|
->filter(fn ($item) => $item['skor'] < 3)
|
||||||
|
->sortBy('skor')
|
||||||
|
->values();
|
||||||
|
|
||||||
|
$specialPattern = $this->detectSpecialPattern(
|
||||||
|
$segmen,
|
||||||
|
$dimensions,
|
||||||
|
$skorPetani
|
||||||
|
);
|
||||||
|
|
||||||
|
$title = $this->buildProfileTitle(
|
||||||
|
$segmen,
|
||||||
|
$specialPattern,
|
||||||
|
$barriers
|
||||||
|
);
|
||||||
|
|
||||||
|
$narrative = $this->buildNarrative(
|
||||||
|
$segmen,
|
||||||
|
$specialPattern,
|
||||||
|
$strengths,
|
||||||
|
$barriers
|
||||||
|
);
|
||||||
|
|
||||||
|
$recommendations = $this->buildRecommendations(
|
||||||
|
$specialPattern,
|
||||||
|
$barriers
|
||||||
|
);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'skor_akhir' => $skorAkhir,
|
||||||
|
'segmen' => $segmen,
|
||||||
|
'title' => $title,
|
||||||
|
'dimensions' => $dimensions,
|
||||||
|
'components' => $components,
|
||||||
|
'strengths' => $strengths,
|
||||||
|
'barriers' => $barriers,
|
||||||
|
'special_pattern' => $specialPattern,
|
||||||
|
'narrative' => $narrative,
|
||||||
|
'recommendations' => $recommendations,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function normalizeScore($score): ?float
|
||||||
|
{
|
||||||
|
if ($score === null || $score === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$score = (float) $score;
|
||||||
|
|
||||||
|
if ($score <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $score;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getSegmen(?float $score): string
|
||||||
|
{
|
||||||
|
if ($score === null) {
|
||||||
|
return 'Belum Dinilai';
|
||||||
|
}
|
||||||
|
|
||||||
|
return match (true) {
|
||||||
|
$score >= 4.0 => 'Penggerak',
|
||||||
|
$score >= 3.0 => 'Perintis',
|
||||||
|
$score >= 2.0 => 'Pemerhati',
|
||||||
|
default => 'Pemula',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getDimensionLevel(?float $score): string
|
||||||
|
{
|
||||||
|
if ($score === null) {
|
||||||
|
return 'belum_dinilai';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($score <= self::DIMENSION_LOW_MAX) {
|
||||||
|
return 'rendah';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($score <= self::DIMENSION_MEDIUM_MAX) {
|
||||||
|
return 'sedang';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'tinggi';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function detectSpecialPattern(
|
||||||
|
string $segmen,
|
||||||
|
array $dimensions,
|
||||||
|
SkorPetani $skorPetani
|
||||||
|
): ?array {
|
||||||
|
|
||||||
|
$d2 = $dimensions['d2']['level'];
|
||||||
|
$d4 = $dimensions['d4']['level'];
|
||||||
|
$d6 = $dimensions['d6']['level'];
|
||||||
|
|
||||||
|
if (
|
||||||
|
$segmen === 'Perintis' &&
|
||||||
|
$d4 === 'tinggi' &&
|
||||||
|
$d2 === 'rendah' &&
|
||||||
|
$d6 === 'sedang'
|
||||||
|
) {
|
||||||
|
return [
|
||||||
|
'kode' => 'perintis_teknis',
|
||||||
|
'nama' => 'Perintis dengan Hambatan Teknis',
|
||||||
|
'prioritas' => 'gap',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
$segmen === 'Perintis' &&
|
||||||
|
$d4 === 'tinggi' &&
|
||||||
|
in_array($d2, ['sedang', 'tinggi']) && $d6 === 'rendah'
|
||||||
|
) {
|
||||||
|
return [
|
||||||
|
'kode' => 'perintis_pasar',
|
||||||
|
'nama' => 'Perintis dengan Hambatan Pasar',
|
||||||
|
'prioritas' => 'pasar',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
$segmen === 'Pemerhati' &&
|
||||||
|
$d4 === 'sedang' &&
|
||||||
|
$d2 === 'rendah' &&
|
||||||
|
$d6 === 'sedang'
|
||||||
|
) {
|
||||||
|
return [
|
||||||
|
'kode' => 'pemerhati_teknis',
|
||||||
|
'nama' => 'Pemerhati Teknis',
|
||||||
|
'prioritas' => 'gap',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
$segmen === 'Pemula' &&
|
||||||
|
$d4 === 'rendah' &&
|
||||||
|
$d2 === 'rendah' &&
|
||||||
|
$d6 === 'rendah'
|
||||||
|
) {
|
||||||
|
return [
|
||||||
|
'kode' => 'pemula_struktural',
|
||||||
|
'nama' => 'Pemula Struktural',
|
||||||
|
'prioritas' => 'struktural',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildProfileTitle(
|
||||||
|
string $segmen,
|
||||||
|
?array $specialPattern,
|
||||||
|
$barriers
|
||||||
|
): string {
|
||||||
|
if ($specialPattern) {
|
||||||
|
return $specialPattern['nama'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($barriers->isNotEmpty()) {
|
||||||
|
$mainBarrier = $barriers->first();
|
||||||
|
return $segmen . ' dengan Prioritas ' . $mainBarrier['short'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $segmen . ' dengan Profil Relatif Seimbang';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildNarrative(
|
||||||
|
string $segmen,
|
||||||
|
?array $specialPattern,
|
||||||
|
$strengths,
|
||||||
|
$barriers
|
||||||
|
): string {
|
||||||
|
if ($specialPattern) {
|
||||||
|
return match ($specialPattern['kode']) {
|
||||||
|
'perintis_teknis' =>
|
||||||
|
'Petani memiliki fondasi sosial-ekonomi yang relatif siap '
|
||||||
|
. 'untuk berkembang, tetapi penerapannya belum sepenuhnya '
|
||||||
|
. 'tercermin dalam praktik budidaya. Hambatan utama berada '
|
||||||
|
. 'pada aspek teknis di lapangan.',
|
||||||
|
|
||||||
|
'perintis_pasar' =>
|
||||||
|
'Petani memiliki fondasi sosial-ekonomi dan kesiapan '
|
||||||
|
. 'budidaya yang relatif baik, tetapi manfaat ekonominya '
|
||||||
|
. 'masih dibatasi oleh rantai nilai dan akses pasar.',
|
||||||
|
|
||||||
|
'pemerhati_teknis' =>
|
||||||
|
'Petani telah memiliki sebagian fondasi untuk berkembang, '
|
||||||
|
. 'namun praktik budidaya masih menjadi hambatan utama. '
|
||||||
|
. 'Pendekatan berbasis demonstrasi hasil nyata akan lebih '
|
||||||
|
. 'relevan sebelum intervensi teknis yang lebih lanjut.',
|
||||||
|
|
||||||
|
'pemula_struktural' =>
|
||||||
|
'Petani menghadapi hambatan pada beberapa dimensi sekaligus. '
|
||||||
|
. 'Kondisi sosial-ekonomi, praktik budidaya, serta akses '
|
||||||
|
. 'pasar perlu dibaca bersama untuk menentukan hambatan '
|
||||||
|
. 'mendasar yang paling mendesak.',
|
||||||
|
|
||||||
|
default =>
|
||||||
|
$this->buildGenericNarrative($segmen, $strengths, $barriers),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->buildGenericNarrative($segmen, $strengths, $barriers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildGenericNarrative(
|
||||||
|
string $segmen,
|
||||||
|
$strengths,
|
||||||
|
$barriers
|
||||||
|
): string {
|
||||||
|
|
||||||
|
$text = 'Petani berada pada segmen ' . $segmen . '. ';
|
||||||
|
if ($strengths->isNotEmpty()) {
|
||||||
|
$strengthNames = $strengths->pluck('nama')->implode(' dan ');
|
||||||
|
$text .= 'Kekuatan relatif terlihat pada ' . $strengthNames . '. ';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($barriers->isNotEmpty()) {
|
||||||
|
$barrierNames = $barriers->take(3)->pluck('nama')->implode(', ');
|
||||||
|
$text .=
|
||||||
|
'Area yang masih memerlukan perhatian terutama pada ' . $barrierNames . '. Prioritas intervensi sebaiknya mengikuti ' . 'hambatan dengan skor paling rendah.';
|
||||||
|
} else {
|
||||||
|
$text .= 'Tidak terdapat komponen dengan skor rendah yang ' . 'menonjol. Pendampingan dapat difokuskan pada ' . 'pemeliharaan dan penguatan capaian yang sudah ada.';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $text;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildRecommendations(
|
||||||
|
?array $specialPattern,
|
||||||
|
$barriers
|
||||||
|
): array {
|
||||||
|
if ($specialPattern) {
|
||||||
|
$specialRecommendation = match ($specialPattern['kode']) {
|
||||||
|
'perintis_teknis' => [
|
||||||
|
'Prioritaskan pendampingan GAP langsung di lapangan.',
|
||||||
|
'Perkuat koneksi petani terhadap sumber input dan pelatihan teknis.',
|
||||||
|
],
|
||||||
|
'perintis_pasar' => [
|
||||||
|
'Perkuat koneksi ke saluran pasar yang lebih baik.',
|
||||||
|
'Fasilitasi akses pembeli, negosiasi, atau penguatan koperasi.',
|
||||||
|
],
|
||||||
|
'pemerhati_teknis' => [
|
||||||
|
'Gunakan demonstrasi lapangan untuk menunjukkan hasil nyata.',
|
||||||
|
'Lakukan pendampingan teknis secara bertahap sebelum pelatihan formal.',
|
||||||
|
],
|
||||||
|
'pemula_struktural' => [
|
||||||
|
'Identifikasi hambatan dasar seperti lahan, hutang, atau logistik.',
|
||||||
|
'Tangani hambatan struktural sebelum mendorong adopsi praktik baru.',
|
||||||
|
],
|
||||||
|
default => [],
|
||||||
|
};
|
||||||
|
if (!empty($specialRecommendation)) {
|
||||||
|
return $specialRecommendation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$recommendationMap = [
|
||||||
|
'motivasi' => 'Gunakan demonstrasi hasil nyata, role model, dan pendekatan perubahan secara bertahap.',
|
||||||
|
'ekonomi' => 'Perkuat ruang gerak ekonomi rumah tangga sebelum mendorong investasi atau perubahan praktik yang berisiko.',
|
||||||
|
'gap' => 'Prioritaskan pendampingan praktik budidaya dan GAP langsung di kebun.',
|
||||||
|
'kelembagaan' => 'Perkuat keterlibatan petani dalam kelompok tani sebagai ruang belajar dan penguatan posisi tawar.',
|
||||||
|
'keuangan' => 'Tinjau akses keuangan formal serta kemungkinan ikatan hutang panen atau ijon yang membatasi ruang gerak petani.',
|
||||||
|
'pasar' => 'Perkuat koneksi dengan pembeli dan saluran pasar alternatif serta kemampuan negosiasi petani.',
|
||||||
|
];
|
||||||
|
|
||||||
|
return $barriers->take(3)->map(
|
||||||
|
fn ($item) =>
|
||||||
|
$recommendationMap[$item['key']] ?? null
|
||||||
|
)->filter()->values()->all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,651 @@
|
|||||||
|
@extends('layout.main')
|
||||||
|
|
||||||
|
@push('styles')
|
||||||
|
<link rel="stylesheet" href="{{ asset('assets/vendor/libs/apex-charts/apex-charts.css') }}" />
|
||||||
|
<style>
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.border-start-lg {
|
||||||
|
border-left: 1px solid var(--bs-border-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 991.98px) {
|
||||||
|
.border-start-lg {
|
||||||
|
border-top: 1px solid var(--bs-border-color);
|
||||||
|
padding-top: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container-xxl flex-grow-1 container-p-y">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card mb-6">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row align-items-center gy-5">
|
||||||
|
<div class="col-lg-7">
|
||||||
|
<div class="d-flex flex-column flex-sm-row align-items-center align-items-sm-start gap-4">
|
||||||
|
<div class="flex-shrink-0 position-relative">
|
||||||
|
<img id="fotoPreview" src="{{ asset('assets/img/avatars/3.jpg') }}"
|
||||||
|
alt="Foto profil petani"
|
||||||
|
class="rounded-circle shadow-sm border border-2 border-primary-subtle"
|
||||||
|
style="width: 96px; height: 96px; object-fit: cover; display: block;"/>
|
||||||
|
<a href="javascript:void(0)" class="btn btn-sm btn-icon btn-primary rounded-circle position-absolute bottom-0 end-0" style="width: 28px; height: 28px;">
|
||||||
|
<i class="icon-base ti tabler-settings icon-xs"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="flex-grow-1 text-center text-sm-start">
|
||||||
|
<div class="d-flex align-items-center justify-content-center justify-content-sm-start flex-wrap gap-2 mb-1">
|
||||||
|
<h4 class="mb-0">{{ $petani->nama }}</h4>
|
||||||
|
<span class="badge bg-label-secondary">NIK: {{ $ktpMasked }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-center justify-content-center justify-content-sm-start flex-wrap gap-2 mb-3">
|
||||||
|
<span class="text-body-secondary">{{ \Carbon\Carbon::parse($petani->tanggal_lahir)->age }} tahun</span>
|
||||||
|
<span class="text-body-secondary">•</span>
|
||||||
|
<span class="badge bg-label-secondary">{{ $petani->pendidikan_terakhir }}</span>
|
||||||
|
<span class="badge bg-label-secondary">{{ $petani->status_perkawinan }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex flex-wrap justify-content-center justify-content-sm-start gap-2 mb-3">
|
||||||
|
<span class="badge bg-label-secondary d-flex align-items-center gap-1">
|
||||||
|
<i class="icon-base ti tabler-map-pin icon-xs"></i>
|
||||||
|
{{ $desaKelurahan->nama }}, {{ $desaKelurahan->kecamatan->nama }}
|
||||||
|
</span>
|
||||||
|
<span class="badge bg-label-secondary d-flex align-items-center gap-1">
|
||||||
|
<i class="icon-base ti tabler-chocolate icon-xs"></i>
|
||||||
|
{{ $komoditas->first()->nama }}
|
||||||
|
</span>
|
||||||
|
@if($petani->sertifikat === 1)
|
||||||
|
<span class="badge bg-label-secondary d-flex align-items-center gap-1">
|
||||||
|
<i class="icon-base ti tabler-file-certificate icon-xs"></i>
|
||||||
|
Hak Milik (SHM)
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-5">
|
||||||
|
<div class="ps-lg-5 border-start-lg">
|
||||||
|
<div class="d-flex justify-content-between align-items-start mb-3">
|
||||||
|
<div>
|
||||||
|
<div class="text-uppercase text-body-secondary small fw-medium mb-1">
|
||||||
|
Skor Kesiapan Adopsi
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-baseline gap-1">
|
||||||
|
<h2 class="mb-0 text-primary">
|
||||||
|
{{ number_format($skorPetani->skor_kesiapan_adopsi, 1) }}
|
||||||
|
</h2>
|
||||||
|
<span class="text-body-secondary"> / 5.0 </span>
|
||||||
|
<div class="d-flex flex-wrap justify-content-center justify-content-sm-start gap-2">
|
||||||
|
<span class="badge bg-label-info d-flex align-items-center gap-1">
|
||||||
|
@if($skorPetani->skor_kesiapan_adopsi < 2.0)
|
||||||
|
Pemula
|
||||||
|
@elseif($skorPetani->skor_kesiapan_adopsi >= 2.0 && $skorPetani->skor_kesiapan_adopsi < 3.0)
|
||||||
|
Pemerhati
|
||||||
|
@elseif($skorPetani->skor_kesiapan_adopsi >= 3.0 && $skorPetani->skor_kesiapan_adopsi < 4.0)
|
||||||
|
Perintis
|
||||||
|
@elseif($skorPetani->skor_kesiapan_adopsi >= 4.0)
|
||||||
|
Penggerak
|
||||||
|
@endif
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn btn-primary">
|
||||||
|
<i class="icon-base ti tabler-file-type-pdf icon-sm me-1"></i>
|
||||||
|
Export PDF
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="progress mb-2" style="height: 7px;">
|
||||||
|
<div class="progress-bar" role="progressbar" style="width: {{ ($skorPetani->skor_kesiapan_adopsi / 5.0) * 100 }}%;" aria-valuenow="{{ $skorPetani->skor_kesiapan_adopsi }}" aria-valuemin="0" aria-valuemax="5.0"></div>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex justify-content-between align-items-center flex-wrap gap-2 mb-4">
|
||||||
|
<small class="text-warning">
|
||||||
|
{{ number_format(4.0 - $skorPetani->skor_kesiapan_adopsi, 1) }} poin lagi menuju batas Segmen Penggerak
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex flex-wrap gap-3 text-body-secondary small">
|
||||||
|
<span class="d-flex align-items-center gap-1">
|
||||||
|
<i class="icon-base ti tabler-user-search icon-xs"></i>
|
||||||
|
Enu: {{ $enumerator->nama ?? 'N/A' }}
|
||||||
|
</span>
|
||||||
|
<span class="d-flex align-items-center gap-1">
|
||||||
|
<i class="icon-base ti tabler-calendar-event icon-xs"></i>
|
||||||
|
Terakhir Update: {{ \Carbon\Carbon::parse($petani->updated_at)->format('d M Y : H:i' ) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row g-6">
|
||||||
|
<div class="col-md-6 col-12">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-header">
|
||||||
|
<h5 class="card-title mb-1">Profil Dimensi</h5>
|
||||||
|
<p class="card-subtitle text-body-secondary mb-0">Profil berdasarkan 6 dimensi penilaian</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<div id="dimensionChart"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-12">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-header">
|
||||||
|
<h5 class="card-title mb-1">Skor per Komponen</h5>
|
||||||
|
<p class="card-subtitle text-body-secondary mb-0">Nilai masing-masing komponen penilaian petani</p>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div id="skorKomponenBarChart"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if($profiling)
|
||||||
|
<div class="row mt-6">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card border-start border-4 border-primary">
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
|
<div class="d-flex flex-column flex-md-row align-items-md-center justify-content-between gap-3 mb-4">
|
||||||
|
|
||||||
|
<div class="d-flex align-items-center gap-3">
|
||||||
|
|
||||||
|
<span class="avatar-initial rounded bg-label-info p-2">
|
||||||
|
<i class="icon-base ti tabler-chart-arrows icon-md"></i>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h5 class="card-title mb-1">
|
||||||
|
Profil Hambatan & Rekomendasi Intervensi
|
||||||
|
</h5>
|
||||||
|
|
||||||
|
<p class="text-body-secondary mb-0">
|
||||||
|
Pembacaan multidimensi berdasarkan profil petani
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{{-- Nama Profil --}}
|
||||||
|
<span class="badge bg-label-primary fs-6">
|
||||||
|
{{ $profiling['title'] }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{{-- Narasi --}}
|
||||||
|
<p class="text-body mb-4 lh-lg">
|
||||||
|
{{ $profiling['narrative'] }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
{{-- Kekuatan & Hambatan --}}
|
||||||
|
<div class="row g-4 mb-4">
|
||||||
|
|
||||||
|
{{-- Kekuatan --}}
|
||||||
|
<div class="col-lg-6">
|
||||||
|
|
||||||
|
<div class="mb-2">
|
||||||
|
<small class="text-body-secondary fw-medium">
|
||||||
|
Kekuatan Relatif
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex flex-wrap gap-2">
|
||||||
|
|
||||||
|
@forelse($profiling['strengths'] as $strength)
|
||||||
|
|
||||||
|
<span class="badge bg-label-success d-flex align-items-center gap-1">
|
||||||
|
|
||||||
|
<i class="icon-base ti {{ $strength['icon'] }} icon-xs"></i>
|
||||||
|
|
||||||
|
{{ $strength['short'] }}
|
||||||
|
|
||||||
|
<span class="fw-semibold ms-1">
|
||||||
|
{{ number_format($strength['skor'], 1) }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
|
||||||
|
@empty
|
||||||
|
|
||||||
|
<span class="text-body-secondary small">
|
||||||
|
Belum ada data yang cukup.
|
||||||
|
</span>
|
||||||
|
|
||||||
|
@endforelse
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{{-- Hambatan --}}
|
||||||
|
<div class="col-lg-6">
|
||||||
|
|
||||||
|
<div class="mb-2">
|
||||||
|
<small class="text-body-secondary fw-medium">
|
||||||
|
Area Prioritas
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex flex-wrap gap-2">
|
||||||
|
|
||||||
|
@forelse($profiling['barriers'] as $barrier)
|
||||||
|
|
||||||
|
<span class="badge bg-label-warning d-flex align-items-center gap-1">
|
||||||
|
|
||||||
|
<i class="icon-base ti {{ $barrier['icon'] }} icon-xs"></i>
|
||||||
|
|
||||||
|
{{ $barrier['short'] }}
|
||||||
|
|
||||||
|
<span class="fw-semibold ms-1">
|
||||||
|
{{ number_format($barrier['skor'], 1) }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
|
||||||
|
@empty
|
||||||
|
|
||||||
|
<span class="badge bg-label-success">
|
||||||
|
<i class="icon-base ti tabler-circle-check icon-xs me-1"></i>
|
||||||
|
Tidak ada hambatan utama yang menonjol
|
||||||
|
</span>
|
||||||
|
|
||||||
|
@endforelse
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{{-- Rekomendasi --}}
|
||||||
|
@if(!empty($profiling['recommendations']))
|
||||||
|
|
||||||
|
<div class="border-top pt-4">
|
||||||
|
|
||||||
|
<div class="d-flex align-items-center gap-2 mb-3">
|
||||||
|
|
||||||
|
<i class="icon-base ti tabler-bulb text-warning icon-md"></i>
|
||||||
|
|
||||||
|
<h6 class="mb-0">
|
||||||
|
Rekomendasi Intervensi
|
||||||
|
</h6>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row g-3">
|
||||||
|
|
||||||
|
@foreach($profiling['recommendations'] as $recommendation)
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
|
||||||
|
<div class="d-flex align-items-start gap-3">
|
||||||
|
|
||||||
|
<span class="badge rounded-pill bg-label-primary">
|
||||||
|
{{ $loop->iteration }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="text-body">
|
||||||
|
{{ $recommendation }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script src="{{ asset('assets/vendor/libs/apex-charts/apexcharts.js') }}"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
|
||||||
|
const dimensionScores = [
|
||||||
|
@json((float) ($skorPetani->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi ?? 0)),
|
||||||
|
@json((float) ($skorPetani->skor_komp_2_d4_k2_ekonomi_rumah_tangga ?? 0)),
|
||||||
|
@json((float) ($skorPetani->skor_komp_3_d2_praktik_budidaya_gap ?? 0)),
|
||||||
|
@json((float) ($skorPetani->skor_komp_4_d4_k4_keterlibatan_kelembagaan ?? 0)),
|
||||||
|
@json((float) ($skorPetani->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan ?? 0)),
|
||||||
|
@json((float) ($skorPetani->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar ?? 0))
|
||||||
|
];
|
||||||
|
|
||||||
|
const dimensionLabels = [
|
||||||
|
'Motivasi',
|
||||||
|
'Ekonomi',
|
||||||
|
'GAP',
|
||||||
|
'Kelembagaan',
|
||||||
|
'Keuangan',
|
||||||
|
'Akses Pasar'
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| VUEXY THEME COLORS
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
const primaryColor = config.colors.primary;
|
||||||
|
const secondaryColor = config.colors.secondary;
|
||||||
|
const successColor = config.colors.success;
|
||||||
|
const infoColor = config.colors.info;
|
||||||
|
const warningColor = config.colors.warning;
|
||||||
|
const dangerColor = config.colors.danger;
|
||||||
|
|
||||||
|
const bodyColor = config.colors.bodyColor;
|
||||||
|
const borderColor = config.colors.borderColor;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| DEBUG
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
console.log('Skor Petani:', dimensionScores);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| RADAR CHART
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
const dimensionChartEl = document.querySelector('#dimensionChart');
|
||||||
|
|
||||||
|
if (dimensionChartEl && typeof ApexCharts !== 'undefined') {
|
||||||
|
|
||||||
|
const dimensionChartConfig = {
|
||||||
|
|
||||||
|
chart: {
|
||||||
|
height: 360,
|
||||||
|
type: 'radar',
|
||||||
|
toolbar: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
parentHeightOffset: 0
|
||||||
|
},
|
||||||
|
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: 'Skor',
|
||||||
|
data: dimensionScores
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
labels: dimensionLabels,
|
||||||
|
|
||||||
|
colors: [
|
||||||
|
primaryColor
|
||||||
|
],
|
||||||
|
|
||||||
|
stroke: {
|
||||||
|
width: 2
|
||||||
|
},
|
||||||
|
|
||||||
|
fill: {
|
||||||
|
opacity: 0.18
|
||||||
|
},
|
||||||
|
|
||||||
|
markers: {
|
||||||
|
size: 4,
|
||||||
|
strokeWidth: 0,
|
||||||
|
hover: {
|
||||||
|
size: 6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
dataLabels: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
|
||||||
|
plotOptions: {
|
||||||
|
radar: {
|
||||||
|
size: 125,
|
||||||
|
|
||||||
|
polygons: {
|
||||||
|
strokeColors: borderColor,
|
||||||
|
connectorColors: borderColor,
|
||||||
|
|
||||||
|
fill: {
|
||||||
|
colors: [
|
||||||
|
'transparent'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
xaxis: {
|
||||||
|
labels: {
|
||||||
|
style: {
|
||||||
|
colors: [
|
||||||
|
bodyColor,
|
||||||
|
bodyColor,
|
||||||
|
bodyColor,
|
||||||
|
bodyColor,
|
||||||
|
bodyColor,
|
||||||
|
bodyColor
|
||||||
|
],
|
||||||
|
fontSize: '12px',
|
||||||
|
fontWeight: 500
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
yaxis: {
|
||||||
|
min: 0,
|
||||||
|
max: 5,
|
||||||
|
tickAmount: 5,
|
||||||
|
|
||||||
|
labels: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
tooltip: {
|
||||||
|
y: {
|
||||||
|
formatter: function (value) {
|
||||||
|
return Number(value).toFixed(1) + ' / 5.0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
legend: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const dimensionChart = new ApexCharts(
|
||||||
|
dimensionChartEl,
|
||||||
|
dimensionChartConfig
|
||||||
|
);
|
||||||
|
|
||||||
|
dimensionChart.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| BAR CHART
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
const skorKomponenBarChartEl =
|
||||||
|
document.querySelector('#skorKomponenBarChart');
|
||||||
|
|
||||||
|
if (skorKomponenBarChartEl && typeof ApexCharts !== 'undefined') {
|
||||||
|
|
||||||
|
const skorKomponenBarChartConfig = {
|
||||||
|
|
||||||
|
chart: {
|
||||||
|
type: 'bar',
|
||||||
|
height: 380,
|
||||||
|
toolbar: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
parentHeightOffset: 0
|
||||||
|
},
|
||||||
|
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: 'Skor',
|
||||||
|
data: dimensionScores
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
plotOptions: {
|
||||||
|
bar: {
|
||||||
|
horizontal: true,
|
||||||
|
borderRadius: 4,
|
||||||
|
barHeight: '45%',
|
||||||
|
|
||||||
|
dataLabels: {
|
||||||
|
position: 'top'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
colors: [
|
||||||
|
primaryColor
|
||||||
|
],
|
||||||
|
|
||||||
|
dataLabels: {
|
||||||
|
enabled: true,
|
||||||
|
|
||||||
|
formatter: function (value) {
|
||||||
|
return Number(value).toFixed(1);
|
||||||
|
},
|
||||||
|
|
||||||
|
offsetX: 25,
|
||||||
|
|
||||||
|
style: {
|
||||||
|
fontSize: '12px',
|
||||||
|
fontWeight: 600,
|
||||||
|
colors: [bodyColor]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
xaxis: {
|
||||||
|
categories: [
|
||||||
|
'Motivasi',
|
||||||
|
'Sosial Ekonomi',
|
||||||
|
'Budidaya / GAP',
|
||||||
|
'Kelembagaan',
|
||||||
|
'Akses Keuangan',
|
||||||
|
'Akses Pasar'
|
||||||
|
],
|
||||||
|
|
||||||
|
min: 0,
|
||||||
|
max: 5,
|
||||||
|
tickAmount: 5,
|
||||||
|
|
||||||
|
labels: {
|
||||||
|
formatter: function (value) {
|
||||||
|
return Number(value).toFixed(0);
|
||||||
|
},
|
||||||
|
|
||||||
|
style: {
|
||||||
|
colors: bodyColor,
|
||||||
|
fontSize: '11px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
axisBorder: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
|
||||||
|
axisTicks: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
yaxis: {
|
||||||
|
labels: {
|
||||||
|
style: {
|
||||||
|
colors: bodyColor,
|
||||||
|
fontSize: '12px',
|
||||||
|
fontWeight: 500
|
||||||
|
},
|
||||||
|
|
||||||
|
maxWidth: 150
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
grid: {
|
||||||
|
borderColor: borderColor,
|
||||||
|
strokeDashArray: 4,
|
||||||
|
|
||||||
|
xaxis: {
|
||||||
|
lines: {
|
||||||
|
show: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
yaxis: {
|
||||||
|
lines: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
padding: {
|
||||||
|
right: 30,
|
||||||
|
left: 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
tooltip: {
|
||||||
|
y: {
|
||||||
|
formatter: function (value) {
|
||||||
|
return Number(value).toFixed(1) + ' / 5.0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
legend: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const skorKomponenBarChart = new ApexCharts(
|
||||||
|
skorKomponenBarChartEl,
|
||||||
|
skorKomponenBarChartConfig
|
||||||
|
);
|
||||||
|
|
||||||
|
skorKomponenBarChart.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
@@ -52,6 +52,8 @@ Route::middleware('auth')
|
|||||||
|
|
||||||
Route::get('/dashboard/petani/indeks', [App\Http\Controllers\Web\Dashboard\IndeksPetaniController::class, 'index'])->name('dashboard.indeks-petani');
|
Route::get('/dashboard/petani/indeks', [App\Http\Controllers\Web\Dashboard\IndeksPetaniController::class, 'index'])->name('dashboard.indeks-petani');
|
||||||
|
|
||||||
|
Route::get('/dashboard/profil/petani/{id}',[App\Http\Controllers\Web\Produktivitas\ProfilPetaniController::class, 'index'])->name('dashboard.profil-petani');
|
||||||
|
|
||||||
Route::get('/user-profile', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'index'])->name('userProfile.index');
|
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');
|
Route::get('/user-profile/security', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'security'])->name('userProfile.security');
|
||||||
Route::get('/user-profile/activities', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'activities'])->name('userProfile.activities');
|
Route::get('/user-profile/activities', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'activities'])->name('userProfile.activities');
|
||||||
|
|||||||
Reference in New Issue
Block a user