This commit is contained in:
2026-05-06 15:54:05 +07:00
17 changed files with 372 additions and 77 deletions
@@ -49,18 +49,27 @@ class KolomBasisDataController extends Controller
'kolom' => ['required', 'kolom' => ['required',
'string', 'string',
'regex:/^[a-z0-9]+(_[a-z0-9]+)*$/', 'regex:/^[a-z0-9]+(_[a-z0-9]+)*$/',
Rule::unique('ekosistem_basis_data_kolom')->where(function ($query) use ($request) { Rule::unique('ekosistem_basis_data_kolom')->where(function ($query) use ($tabelId) {
return $query->where('tabel_id', $request->tabel_id)->whereNull('deleted_at'); return $query->where('tabel_id', $tabelId)->whereNull('deleted_at');
}) })
], ],
'label' => ['required', 'string'], 'label' => ['required', 'string'],
'tipe' => ['required', 'string', Rule::in(['varchar', 'integer', 'text', 'date', 'boolean', 'datetime', 'float', 'foreign_key'])], 'tipe' => ['required', 'string',
Rule::in(['varchar', 'integer', 'text', 'date', 'boolean', 'datetime', 'float', 'foreign_key', 'enum'])],
'validasi' => ['nullable', 'json'], 'validasi' => ['nullable', 'json'],
'relasi_tabel' => ['nullable', 'string'], 'relasi_tabel' => ['nullable', 'string'],
'relasi_kolom_id' => ['nullable', 'string'], 'relasi_kolom_id' => ['nullable', 'string'],
'relasi_kolom_label' => ['nullable', 'string'], 'relasi_kolom_label' => ['nullable', 'string'],
'enum_opsi' => ['nullable', 'json'],
]); ]);
if (!empty($validated['enum_opsi'])) {
$validated['enum_opsi'] = json_decode($validated['enum_opsi'], true);
}
if (!empty($validated['validasi'])) {
$validated['validasi'] = json_decode($validated['validasi'], true);
}
KolomBasisData::create([...$validated, KolomBasisData::create([...$validated,
'tabel_id' => $tabelId, 'tabel_id' => $tabelId,
'created_by' => auth()->id(), 'created_by' => auth()->id(),
@@ -123,11 +132,13 @@ class KolomBasisDataController extends Controller
}) })
], ],
'label' => ['required', 'string'], 'label' => ['required', 'string'],
'tipe' => ['required', 'string', Rule::in(['varchar', 'integer', 'text', 'date', 'boolean', 'datetime', 'float', 'foreign_key'])], 'tipe' => ['required', 'string',
Rule::in(['varchar', 'integer', 'text', 'date', 'boolean', 'datetime', 'float', 'foreign_key', 'enum'])],
'validasi' => ['nullable', 'json'], 'validasi' => ['nullable', 'json'],
'relasi_tabel' => ['nullable', 'string'], 'relasi_tabel' => ['nullable', 'string'],
'relasi_kolom_id' => ['nullable', 'string'], 'relasi_kolom_id' => ['nullable', 'string'],
'relasi_kolom_label' => ['nullable', 'string'], 'relasi_kolom_label' => ['nullable', 'string'],
'enum_opsi' => ['nullable', 'json'],
]); ]);
$kolom->update([...$validated, $kolom->update([...$validated,
@@ -13,6 +13,7 @@ use Illuminate\Http\JsonResponse;
use App\Models\Ekosistem\PetaniCPM; use App\Models\Ekosistem\PetaniCPM;
use App\Models\Wilayah\Provinsi; use App\Models\Wilayah\Provinsi;
use App\Models\Pertanian\Komoditas; use App\Models\Pertanian\Komoditas;
use App\Models\Core\Program;
use App\Enums\Pendidikan; use App\Enums\Pendidikan;
use App\Enums\Pekerjaan; use App\Enums\Pekerjaan;
@@ -30,15 +31,34 @@ class PetaniCPMController extends Controller
$perPage = $request->query('per_page', 10); $perPage = $request->query('per_page', 10);
$search = strtolower($request->query('search', '')); $search = strtolower($request->query('search', ''));
$program = null;
$programList = Program::get();
if (app()->has('SystemProgram')) {
$program = app('SystemProgram');
} else {
if ($request->has('program_id') && $request->query('program_id')) {
$programId = $request->query('program_id');
$program = Program::find($programId);
if (!$program) {
abort(400, 'Program tidak ditemukan.');
}
}
}
$petani = PetaniCPM::when($search, function ($query, $search) { $petani = PetaniCPM::when($search, function ($query, $search) {
return $query->where('nama', 'like', "%{$search}%"); return $query->where('nama', 'like', "%{$search}%");
}) })
->when($program, function ($query) use ($program) {
return $query->where('program_id', $program->id);
})
->paginate($perPage); ->paginate($perPage);
return view('ekosistem.petani-cpm.index', compact('petani')); return view('ekosistem.petani-cpm.index', compact('petani', 'program', 'programList'));
} }
public function create(): View public function create(Request $request): View
{ {
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403); abort(403);
@@ -52,8 +72,21 @@ class PetaniCPMController extends Controller
$provinsi = Provinsi::all(); $provinsi = Provinsi::all();
$komoditas = Komoditas::all(); $komoditas = Komoditas::all();
$program = null;
if (app()->has('SystemProgram')) {
$program = app('SystemProgram');
} else {
if ($request->has('program_id') && $request->query('program_id')) {
$programId = $request->query('program_id');
$program = Program::find($programId);
}
}
if (!$program) {
abort(400, 'Program tidak ditemukan.');
}
return view('ekosistem.petani-cpm.add', compact('pendidikan', 'pekerjaan', return view('ekosistem.petani-cpm.add', compact('pendidikan', 'pekerjaan',
'pernikahan', 'statusKeluarga', 'provinsi', 'komoditas')); 'pernikahan', 'statusKeluarga', 'provinsi', 'komoditas', 'program'));
} }
/** /**
@@ -65,6 +98,20 @@ class PetaniCPMController extends Controller
abort(403); abort(403);
} }
if (app()->has('SystemProgram')) {
$program = app('SystemProgram');
} else {
if ($request->has('program_id') && $request->query('program_id')) {
$programId = $request->query('program_id');
$program = Program::find($programId);
if (!$program) {
abort(400, 'Program tidak ditemukan.');
}
} else {
abort(400, 'Program tidak ditemukan.');
}
}
$validatedData = $request->validate([ $validatedData = $request->validate([
'nama' => ['required','string','max:255'], 'nama' => ['required','string','max:255'],
'jenis_kelamin' => ['required','boolean'], 'jenis_kelamin' => ['required','boolean'],
@@ -88,16 +135,17 @@ class PetaniCPMController extends Controller
]); ]);
PetaniCPM::create([...$validatedData, PetaniCPM::create([...$validatedData,
'program_id' => $program->id,
'created_by' => auth()->id(), 'created_by' => auth()->id(),
'updated_by' => auth()->id()]); 'updated_by' => auth()->id()]);
return redirect()->route('petani-cpm.index')->with('success', 'Data petani CPM berhasil ditambahkan.'); return redirect()->route('petani-cpm.index', ['program_id' => $program->id])->with('success', 'Data petani CPM berhasil ditambahkan.');
} }
/** /**
* Display the specified resource. * Display the specified resource.
*/ */
public function show(string $id) public function show(string $id): View
{ {
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403); abort(403);
@@ -111,12 +159,26 @@ class PetaniCPMController extends Controller
/** /**
* Show the form for editing the specified resource. * Show the form for editing the specified resource.
*/ */
public function edit(string $id) public function edit(Request $request, string $id): View
{ {
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) { if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
abort(403); abort(403);
} }
if (app()->has('SystemProgram')) {
$program = app('SystemProgram');
} else {
if ($request->has('program_id') && $request->query('program_id')) {
$programId = $request->query('program_id');
$program = Program::find($programId);
if (!$program) {
abort(400, 'Program tidak ditemukan.');
}
} else {
abort(400, 'Program tidak ditemukan.');
}
}
$petani = PetaniCPM::findOrFail($id); $petani = PetaniCPM::findOrFail($id);
$pendidikan = Pendidikan::options(); $pendidikan = Pendidikan::options();
@@ -128,7 +190,7 @@ class PetaniCPMController extends Controller
$komoditas = Komoditas::all(); $komoditas = Komoditas::all();
return view('ekosistem.petani-cpm.edit', compact('petani', 'pendidikan', 'pekerjaan', return view('ekosistem.petani-cpm.edit', compact('petani', 'pendidikan', 'pekerjaan',
'pernikahan', 'statusKeluarga', 'provinsi', 'komoditas')); 'pernikahan', 'statusKeluarga', 'provinsi', 'komoditas', 'program'));
} }
/** /**
@@ -140,6 +202,20 @@ class PetaniCPMController extends Controller
abort(403); abort(403);
} }
if (app()->has('SystemProgram')) {
$program = app('SystemProgram');
} else {
if ($request->has('program_id') && $request->query('program_id')) {
$programId = $request->query('program_id');
$program = Program::find($programId);
if (!$program) {
abort(400, 'Program tidak ditemukan.');
}
} else {
abort(400, 'Program tidak ditemukan.');
}
}
$petani = PetaniCPM::findOrFail($id); $petani = PetaniCPM::findOrFail($id);
$validatedData = $request->validate([ $validatedData = $request->validate([
@@ -75,6 +75,23 @@ class ValueBasisDataController extends Controller
END END
) AS \"{$k->kolom}\" ) AS \"{$k->kolom}\"
"; ";
} elseif ($k->tipe == 'enum') {
$selects[] = "
MAX(
CASE
WHEN kolom_id = {$k->id}
THEN (
SELECT elem->>'label'
FROM ekosistem_basis_data_kolom k,
jsonb_array_elements(k.enum_opsi::jsonb) AS elem
WHERE k.id = kolom_id
AND elem->>'value' = value_enum
LIMIT 1
)
ELSE NULL
END
) AS \"{$k->kolom}\"
";
} else { } else {
$selects[] = " $selects[] = "
MAX( MAX(
@@ -150,6 +167,7 @@ class ValueBasisDataController extends Controller
abort(404, 'Data kolom tidak ditemukan untuk tabel ini.'); abort(404, 'Data kolom tidak ditemukan untuk tabel ini.');
} }
$program = null;
if (app()->has('SystemProgram')) { if (app()->has('SystemProgram')) {
$program = app('SystemProgram'); $program = app('SystemProgram');
} else { } else {
@@ -177,6 +195,7 @@ class ValueBasisDataController extends Controller
} }
} }
$list_relasi = collect($list_relasi); $list_relasi = collect($list_relasi);
// dd($kolom->where('tipe', 'enum')->first()?->enum_opsi);
return view('ekosistem.value-basis-data.add', compact('tabel', 'kolom', 'program', 'list_relasi')); return view('ekosistem.value-basis-data.add', compact('tabel', 'kolom', 'program', 'list_relasi'));
} }
@@ -249,12 +268,63 @@ class ValueBasisDataController extends Controller
/** /**
* Display the specified resource. * Display the specified resource.
*/ */
public function show(string $id) public function show(Request $request, string $tabelId, string $id): View
{ {
// if (!Gate::any(['super_admin', 'admin'])) {
abort(403);
} }
public function edit(Request $request, string $tabelId, string $id) $tabel = TabelBasisData::find($tabelId);
if (!$tabel) {
abort(404, 'Data tabel tidak ditemukan.');
}
$kolom = KolomBasisData::where('tabel_id', $tabelId)->get();
if ($kolom->isEmpty()) {
abort(404, 'Data kolom tidak ditemukan untuk tabel ini.');
}
if (app()->has('SystemProgram')) {
$program = app('SystemProgram');
} else {
if ($request->has('program_id') && $request->query('program_id')) {
$programId = $request->query('program_id');
$program = Program::find($programId);
if (!$program) {
abort(400, 'Program tidak ditemukan.');
}
} else {
abort(400, 'Program tidak ditemukan.');
}
}
$values = ValueBasisData::query()
->where('tabel_id', $tabelId)
->where('value_id', $id)
->where('program_id', $program->id)
->get();
if ($values->isEmpty()) {
abort(404, 'Data tidak ditemukan.');
}
foreach ($values as $v) {
$k = $kolom->where('id', $v->kolom_id)->first();
if ($k->tipe == 'foreign_key') {
$v->value_relasi_label = DB::table($k->relasi_tabel)->where($k->relasi_kolom_id, $v->value_relasi)->value($k->relasi_kolom_label);
} else if ($k->tipe == 'enum') {
$opsi = collect($k->enum_opsi);
$found = $opsi->first(function ($item) use ($v) {
return (string) $item['value'] === (string) $v->value_enum;
});
$v->value_enum_label = $found['label'] ?? null;
}
}
$value_id = $id;
return view('ekosistem.value-basis-data.view', compact('tabel', 'kolom', 'program', 'values', 'value_id'));
}
public function edit(Request $request, string $tabelId, string $id): View
{ {
if (!Gate::any(['super_admin', 'admin'])) { if (!Gate::any(['super_admin', 'admin'])) {
abort(403); abort(403);
@@ -316,7 +386,7 @@ class ValueBasisDataController extends Controller
/** /**
* Update the specified resource in storage. * Update the specified resource in storage.
*/ */
public function update(Request $request, string $tabelId, string $id) public function update(Request $request, string $tabelId, string $id): RedirectResponse
{ {
if (!Gate::any(['super_admin', 'admin'])) { if (!Gate::any(['super_admin', 'admin'])) {
abort(403); abort(403);
@@ -407,7 +477,7 @@ class ValueBasisDataController extends Controller
/** /**
* Remove the specified resource from storage. * Remove the specified resource from storage.
*/ */
public function destroy(Request $request, string $tabelId, string $id) public function destroy(Request $request, string $tabelId, string $id): RedirectResponse
{ {
if (!Gate::any(['super_admin', 'admin'])) { if (!Gate::any(['super_admin', 'admin'])) {
abort(403); abort(403);
@@ -13,6 +13,12 @@ class KeluargaController extends Controller
{ {
public function index(Request $request) public function index(Request $request)
{ {
// 1. Ambil data dinamis untuk Summary Cards
$totalKeluarga = Keluarga::count();
$dokumenLengkap = Keluarga::whereNotNull('file_kk')->count();
$totalDesa = Keluarga::distinct('desa_kelurahan_id')->count('desa_kelurahan_id');
// 2. Query bawaan untuk tabel
$query = Keluarga::with(['desakelurahan', 'adat'])->orderBy('created_at', 'desc'); $query = Keluarga::with(['desakelurahan', 'adat'])->orderBy('created_at', 'desc');
if ($request->search) { if ($request->search) {
@@ -20,48 +26,9 @@ class KeluargaController extends Controller
} }
$keluarga = $query->paginate($request->per_page ?? 10); $keluarga = $query->paginate($request->per_page ?? 10);
return view('master.keluarga.index', compact('keluarga'));
}
public function create() // 3. Tambahkan variabel card ke dalam compact()
{ return view('master.keluarga.index', compact('keluarga', 'totalKeluarga', 'dokumenLengkap', 'totalDesa'));
$provinsi = Provinsi::orderBy('nama', 'asc')->get();
return view('master.keluarga.add', compact('provinsi'));
}
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'kk' => ['required', 'string', 'min:16', 'max:16'],
'desa_kelurahan_id' => ['required'],
'adat_id' => ['nullable'],
'file_kk' => ['nullable', 'file', 'mimes:jpeg,jpg,png,pdf', 'max:2048'],
]);
if ($validator->fails()) {
return response()->json(['status' => 'error', 'errors' => $validator->errors()], 422);
}
$pathKk = null;
$fileNameKk = null;
if ($request->hasFile('file_kk')) {
$file = $request->file('file_kk');
$fileNameKk = $file->getClientOriginalName();
$pathKk = $file->store('uploads/keluarga', 'public');
}
Keluarga::create([
'kk' => $request->kk,
'desa_kelurahan_id' => $request->desa_kelurahan_id,
'adat_id' => $request->adat_id,
'path_kk' => $pathKk,
'file_kk' => $fileNameKk,
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
return response()->json(['status' => 'success', 'message' => 'Data Keluarga berhasil ditambahkan.']);
} }
public function show($id) public function show($id)
+2
View File
@@ -25,10 +25,12 @@ class KolomBasisData extends Model
'relasi_tabel', 'relasi_tabel',
'relasi_kolom_id', 'relasi_kolom_id',
'relasi_kolom_label', 'relasi_kolom_label',
'enum_opsi',
]; ];
protected $casts = [ protected $casts = [
'validasi' => 'array', 'validasi' => 'array',
'enum_opsi' => 'array',
]; ];
protected static function booted() protected static function booted()
+1
View File
@@ -44,6 +44,7 @@ class PetaniCPM extends Model
'created_by', 'created_by',
'updated_by', 'updated_by',
'deleted_by', 'deleted_by',
'program_id',
]; ];
protected $casts = [ protected $casts = [
+1
View File
@@ -31,6 +31,7 @@ class ValueBasisData extends Model
'updated_by', 'updated_by',
'deleted_by', 'deleted_by',
'value_relasi', 'value_relasi',
'value_enum',
]; ];
public function tabel(): BelongsTo public function tabel(): BelongsTo
@@ -16,6 +16,8 @@ return new class extends Migration
$table->string('relasi_tabel')->nullable(); $table->string('relasi_tabel')->nullable();
$table->string('relasi_kolom_id')->nullable(); $table->string('relasi_kolom_id')->nullable();
$table->string('relasi_kolom_label')->nullable(); $table->string('relasi_kolom_label')->nullable();
$table->jsonb('enum_opsi')->nullable();
}); });
DB::statement("alter table public.ekosistem_basis_data_kolom drop constraint ekosistem_basis_data_kolom_tipe_check;"); DB::statement("alter table public.ekosistem_basis_data_kolom drop constraint ekosistem_basis_data_kolom_tipe_check;");
@@ -29,12 +31,18 @@ return new class extends Migration
'date'::character varying, 'date'::character varying,
'datetime'::character varying, 'datetime'::character varying,
'text'::character varying, 'text'::character varying,
'foreign_key'::character varying 'foreign_key'::character varying,
'enum'::character varying
])::text[]))) ])::text[])))
"); ");
Schema::table('ekosistem_basis_data_value', function (Blueprint $table) { Schema::table('ekosistem_basis_data_value', function (Blueprint $table) {
$table->integer('value_relasi')->nullable(); $table->integer('value_relasi')->nullable();
$table->string('value_enum')->nullable();
});
Schema::table('ekosistem_petani_cpm', function (Blueprint $table) {
$table->foreignId('program_id')->nullable()->constrained('core_program')->nullOnDelete();
}); });
} }
@@ -35,6 +35,7 @@
<option value="datetime">Datetime</option> <option value="datetime">Datetime</option>
<option value="text">Text</option> <option value="text">Text</option>
<option value="foreign_key">Relasi</option> <option value="foreign_key">Relasi</option>
<option value="enum">Enum</option>
</select> </select>
</div> </div>
<div class="mb-6 form-control-validation" id="relasi-form-tabel" style="display: none;"> <div class="mb-6 form-control-validation" id="relasi-form-tabel" style="display: none;">
@@ -49,6 +50,11 @@
<label class="form-label" for="add-kolom-relasi-kolom-label">Kolom Relasi (Label)<span class="text-danger">*</span></label> <label class="form-label" for="add-kolom-relasi-kolom-label">Kolom Relasi (Label)<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="add-kolom-relasi-kolom-label" name="relasi_kolom_label" placeholder="Cth: Nama Petani" /> <input type="text" class="form-control" id="add-kolom-relasi-kolom-label" name="relasi_kolom_label" placeholder="Cth: Nama Petani" />
</div> </div>
<div class="mb-6 form-control-validation" id="enum-form-opsi" style="display: none;">
<label class="form-label" for="add-kolom-enum-opsi" >Opsi Enum<span class="text-danger">*</span></label>
<textarea class="form-control" id="add-kolom-enum-opsi" name="enum_opsi" value="1"
placeholder='Cth: [{"label": "Satu Pilihan", "value": "satu"}, {"label": "Dua Saja", "value": "dua"}]'></textarea>
</div>
<div class="mb-6 form-control-validation"> <div class="mb-6 form-control-validation">
<label class="form-label" for="add-kolom-validasi">Validasi<span class="text-danger">*</span></label> <label class="form-label" for="add-kolom-validasi">Validasi<span class="text-danger">*</span></label>
<textarea class="form-control" id="add-kolom-validasi" name="validasi" value="1" placeholder="Cth: required"></textarea> <textarea class="form-control" id="add-kolom-validasi" name="validasi" value="1" placeholder="Cth: required"></textarea>
@@ -78,8 +84,14 @@
$('#relasi-form-kolom').hide(); $('#relasi-form-kolom').hide();
$('#relasi-form-kolom-label').hide(); $('#relasi-form-kolom-label').hide();
} }
if ($(this).val() === 'enum') {
$('#enum-form-opsi').show();
} else {
$('#enum-form-opsi').hide();
}
}); });
$.validator.addMethod("snakecase", function(value, element) { $.validator.addMethod("snakecase", function(value, element) {
return this.optional(element) || /^[a-z0-9]+(_[a-z0-9]+)*$/.test(value); return this.optional(element) || /^[a-z0-9]+(_[a-z0-9]+)*$/.test(value);
}, "Gunakan format snake_case (huruf kecil dan underscore)"); }, "Gunakan format snake_case (huruf kecil dan underscore)");
@@ -8,7 +8,7 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<form id="addNewPetaniForm" action="{{ route('petani-cpm.store') }}" method="POST" > <form id="addNewPetaniForm" action="{{ route('petani-cpm.store', ['program_id' => $program->id]) }}" method="POST" >
@csrf @csrf
@if ($errors->any()) @if ($errors->any())
@@ -8,7 +8,7 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<form id="addNewPetaniForm" action="{{ route('petani-cpm.update', $petani->id) }}" method="POST" > <form id="addNewPetaniForm" action="{{ route('petani-cpm.update', [$petani->id, 'program_id' => $program->id]) }}" method="POST" >
@csrf @csrf
@method('PUT') @method('PUT')
@@ -71,7 +71,7 @@
</div> </div>
<div class="card-body border-bottom pt-4"> <div class="card-body border-bottom pt-4">
<form method="GET" action="{{ route('tabel.index') }}" class="d-flex justify-content-between align-items-center row gap-3 gap-md-0"> <form method="GET" action="{{ route('petani-cpm.index') }}" class="d-flex justify-content-between align-items-center row gap-3 gap-md-0">
<div class="col-md-auto"> <div class="col-md-auto">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<label class="me-2 text-nowrap">Show</label> <label class="me-2 text-nowrap">Show</label>
@@ -84,11 +84,26 @@
</div> </div>
</div> </div>
<div class="col-md-auto d-flex gap-2"> <div class="col-md-auto d-flex gap-2">
@if (app()->has('SystemProgram'))
@else
<div class="col-md-auto">
<div class="d-flex align-items-center">
<label class="me-2 text-nowrap">Program</label>
<select name="program_id" class="form-select form-select-sm w-auto" onchange="this.form.submit()" id="select-program">
<option value="">Pilih Program</option>
@foreach($programList as $prog)
<option value="{{ $prog->id }}" {{ request('program_id') == $prog->id ? 'selected' : '' }}>{{ $prog->nama }}</option>
@endforeach
</select>
</div>
</div>
@endif
<div class="input-group input-group-sm w-auto"> <div class="input-group input-group-sm w-auto">
<input type="text" name="search" class="form-control" placeholder="Cari Nama Petani..." value="{{ request('search') }}"> <input type="text" name="search" class="form-control" placeholder="Cari Nama Petani..." value="{{ request('search') }}">
<button type="submit" class="btn btn-outline-primary"><i class="ti tabler-search"></i></button> <button type="submit" class="btn btn-outline-primary"><i class="ti tabler-search"></i></button>
</div> </div>
<a href="{{ route('petani-cpm.create') }}" class="btn btn-sm btn-primary"> <a href="{{ route('petani-cpm.create', ['program_id' => request('program_id')]) }}" class="btn btn-sm btn-primary"
style="display: {{ request('program_id') ? 'flex' : 'none' }};">
<i class="ti tabler-plus me-1"></i> Tambah <i class="ti tabler-plus me-1"></i> Tambah
</a> </a>
</div> </div>
@@ -117,7 +132,7 @@
<td><span class="text-muted">{{ $p->desaKelurahan?->nama }}, {{ $p->desaKelurahan?->kecamatan?->nama }}, {{ $p->desaKelurahan?->kecamatan?->kabupatenKota?->nama }}, {{ $p->desaKelurahan?->kecamatan?->kabupatenKota?->provinsi?->nama }}</span></td> <td><span class="text-muted">{{ $p->desaKelurahan?->nama }}, {{ $p->desaKelurahan?->kecamatan?->nama }}, {{ $p->desaKelurahan?->kecamatan?->kabupatenKota?->nama }}, {{ $p->desaKelurahan?->kecamatan?->kabupatenKota?->provinsi?->nama }}</span></td>
<td> <td>
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<a href="{{ route('petani-cpm.edit', $p->id) }}" class="btn btn-icon btn-text-secondary rounded-pill edit-record"><i class="ti tabler-edit ti-md"></i></a> <a href="{{ route('petani-cpm.edit', [$p->id, 'program_id' => $p->program_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="{{ $p->id }}" data-nama="{{ $p->nama }}"><i class="ti tabler-trash ti-md"></i></a> <a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $p->id }}" data-nama="{{ $p->nama }}"><i class="ti tabler-trash ti-md"></i></a>
<a href="{{ route('petani-cpm.show', $p->id) }}" class="btn btn-icon btn-text-secondary rounded-pill view-record"><i class="ti tabler-eye ti-md"></i></a> <a href="{{ route('petani-cpm.show', $p->id) }}" class="btn btn-icon btn-text-secondary rounded-pill view-record"><i class="ti tabler-eye ti-md"></i></a>
</div> </div>
@@ -47,6 +47,12 @@
@endforeach @endforeach
@endif @endif
</select> </select>
@elseif($k->tipe == 'enum')
<select class="form-select tipe-fk @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" name="{{ $k->kolom }}">
@foreach($k->enum_opsi as $opsi)
<option value="{{ $opsi['value'] }}" {{ old($k->kolom) == $opsi['value'] ? 'selected' : '' }}>{{ $opsi['label'] }}</option>
@endforeach
</select>
@else @else
<input type="text" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" <input type="text" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) }}" /> name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) }}" />
@@ -64,6 +64,12 @@
@endforeach @endforeach
@endif @endif
</select> </select>
@elseif($k->tipe == 'enum')
<select class="form-select tipe-fk @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" name="{{ $k->kolom }}">
@foreach($k->enum_opsi as $opsi)
<option value="{{ $opsi['value'] }}" {{ old($k->kolom) ?? $value['value_'.$k->tipe] == $opsi['value'] ? 'selected' : '' }}>{{ $opsi['label'] }}</option>
@endforeach
</select>
@else @else
<input type="text" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" <input type="text" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}" /> name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}" />
@@ -0,0 +1,88 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4">
<h5 class="card-title mb-0">Lihat Data {{ $tabel->label }}</h5>
</div>
<div class="card-body">
<form id="addUpdateDataForm" action="{{ route('tabel.data.update', [$tabel->id, $value_id, 'program_id' => $program->id]) }}" method="POST" >
@csrf
@method('PUT')
<h6 class="mb-3">Informasi {{ $tabel->label }}</h6>
@if (!$program)
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-data-program">Program<span class="text-danger">*</span></label>
<select name="program_id" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
<option value="">Pilih Program</option>
@foreach($programList as $prog)
<option value="{{ $prog->id }}" {{ request('program_id') == $prog->id ? 'selected' : '' }}>{{ $prog->nama }}</option>
@endforeach
</select>
</div>
</div>
@endif
<div class="row">
@foreach($kolom as $k)
<?php
$value = $values->where('kolom_id', $k->id)->first();
?>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-data-{{ $k->kolom }}">{{ $k->label }}<span class="text-danger">*</span></label>
@if($k->tipe == 'varchar')
<input type="text" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" readonly
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}" />
@elseif($k->tipe == 'text')
<textarea class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" readonly
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}">{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}</textarea>
@elseif($k->tipe == 'integer')
<input type="number" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" readonly
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}" step="1" />
@elseif($k->tipe == 'float')
<input type="number" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" readonly
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}" step="any" />
@elseif($k->tipe == 'date')
<input type="date" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" readonly
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}" />
@elseif($k->tipe == 'datetime')
<input type="datetime-local" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" readonly
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}" />
@elseif($k->tipe == 'boolean')
<input type="text" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" readonly
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ (old($k->kolom) ?? $value['value_'.$k->tipe]) == 1 ? 'Ya' : 'Tidak' }}" />
@elseif($k->tipe == 'foreign_key')
<input type="text" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" readonly
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ (old($k->kolom) ?? $value['value_relasi_label']) }}" />
@elseif($k->tipe == 'enum')
<input type="text" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" readonly
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ (old($k->kolom) ?? $value['value_enum_label']) }}" />
@else
<input type="text" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" readonly
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}" />
@endif
@error($k->kolom)<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
@endforeach
</div>
<div class="mt-4 text-end">
<a href="{{ route('tabel.data.index', [$tabel->id, 'program_id' => $program->id]) }}" class="btn btn-label-secondary me-2">Kembali</a>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
});
</script>
@endpush
@@ -1,7 +1,40 @@
@extends('layout.main') @extends('layout.main')
@section('content') @section('content')
<div class="container-xxl flex-grow-1 container-p-y"> <div class="container-xxl flex-grow-3 container-p-y">
<div class="row g-4 mb-6">
<div class="col-md-4">
<x-summary-card
title="Total Keluarga"
count="{{ $totalKeluarga }}"
subtitle="Keseluruhan KK terdaftar"
icon="users"
color="primary"
/>
</div>
<div class="col-md-4">
<x-summary-card
title="Dokumen Lengkap"
count="{{ $dokumenLengkap }}"
subtitle="File KK telah diunggah"
icon="file-check"
color="warning"
/>
</div>
<div class="col-md-4">
<x-summary-card
title="Total Desa/Kelurahan"
count="{{ $totalDesa }}"
subtitle="Cakupan wilayah"
icon="map-pin"
color="danger"
/>
</div>
</div>
<div class="card"> <div class="card">
<div class="card-header border-bottom"> <div class="card-header border-bottom">
<h5 class="card-title mb-0">Data Master Keluarga</h5> <h5 class="card-title mb-0">Data Master Keluarga</h5>
@@ -2,7 +2,7 @@
@section('content') @section('content')
<div class="container-xxl flex-grow-1 container-p-y"> <div class="container-xxl flex-grow-1 container-p-y">
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6"> <div class="mb-6" style="max-width: 350px;">
<x-summary-card <x-summary-card
title="Total Komoditas" title="Total Komoditas"
@@ -12,7 +12,6 @@
color="primary" color="primary"
/> />
</div> </div>
<div class="card"> <div class="card">
<div class="card-header border-bottom"> <div class="card-header border-bottom">