update daftar pengguna

This commit is contained in:
2026-06-15 12:05:03 +07:00
parent 9d3b64a54d
commit d7e2cd7692
9 changed files with 471 additions and 272 deletions
@@ -7,6 +7,7 @@ use Illuminate\Http\Request;
use App\Models\User; use App\Models\User;
use App\Models\Profile; use App\Models\Profile;
use App\Enums\Role; use App\Enums\Role;
use App\Models\Wilayah\Provinsi;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
@@ -68,14 +69,28 @@ class UserController extends Controller
} }
} }
public function create()
{
$roles = Role::cases();
$provinsi = Provinsi::orderBy('nama', 'asc')->get();
return view('konfigurasi.user.add', compact('roles', 'provinsi'));
}
public function store(Request $request) public function store(Request $request)
{ {
$validator = Validator::make($request->all(), [ $validator = Validator::make($request->all(), [
'username' => ['required', 'string', 'max:255', 'unique:users,name'], 'username' => ['required', 'string', 'max:255', 'unique:users,username'],
'name' => ['required', 'string', 'max:255'], 'nama' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:users,email'],
'password' => ['required', 'string', 'min:8', 'confirmed'], 'password' => ['required', 'string', 'min:8', 'confirmed'],
'role' => ['required', 'string'], 'role' => ['required', 'string'],
'telepon' => ['required', 'max:13'],
'desa_kelurahan_id' => ['required'],
'ktp' => ['nullable', 'min:16', 'max:16'],
'kk' => ['nullable', 'min:16', 'max:16'],
'file_ktp' => ['nullable', 'file', 'mimes:jpeg,jpg,png,pdf', 'max:2048'],
'file_kk' => ['nullable', 'file', 'mimes:jpeg,jpg,pdf,png', 'max:2048'],
], [ ], [
'password.confirmed' => 'Konfirmasi password tidak cocok!', 'password.confirmed' => 'Konfirmasi password tidak cocok!',
'password.min' => 'Password minimal 8 karakter!', 'password.min' => 'Password minimal 8 karakter!',
@@ -84,14 +99,25 @@ class UserController extends Controller
]); ]);
if ($validator->fails()) { if ($validator->fails()) {
if ($request->expectsJson()) {
return response()->json(['status' => 'error', 'errors' => $validator->errors()], 422); return response()->json(['status' => 'error', 'errors' => $validator->errors()], 422);
} }
return back()->withErrors($validator)->withInput();
}
try { try {
DB::transaction(function () use ($request) { DB::transaction(function () use ($request) {
$pathKtp = $request->hasFile('file_ktp')
? $request->file('file_ktp')->store('uploads/users/ktp', 'public')
: null;
$pathKk = $request->hasFile('file_kk')
? $request->file('file_kk')->store('uploads/users/kk', 'public')
: null;
$user = User::create([ $user = User::create([
'name' => $request->name, 'name' => $request->nama,
'username' => $request->username, 'username' => $request->username,
'email' => $request->email, 'email' => $request->email,
'password' => Hash::make($request->password), 'password' => Hash::make($request->password),
@@ -104,18 +130,34 @@ class UserController extends Controller
'user_id' => $user->id, 'user_id' => $user->id,
'user_uid' => $user->uid, 'user_uid' => $user->uid,
'role' => $request->role, 'role' => $request->role,
'nama' => $request->name, 'nama' => $request->nama,
'email' => $request->email, 'email' => $request->email,
'telepon' => $request->telepon,
'alamat' => $request->alamat,
'kk' => $request->kk,
'ktp' => $request->ktp,
'desa_kelurahan_id' => $request->desa_kelurahan_id,
'path_kk' => $pathKk,
'path_ktp' => $pathKtp,
'created_by' => auth()->id(), 'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]); ]);
}); });
if ($request->expectsJson()) {
return response()->json([ return response()->json([
'status' => 'success', 'status' => 'success',
'message' => 'User baru berhasil ditambahkan.' 'message' => 'User baru berhasil ditambahkan.'
]); ]);
}
return redirect()->route('users.index')->with('success', 'User baru berhasil ditambahkan.');
} catch (\Exception $e) { } catch (\Exception $e) {
if (!$request->expectsJson()) {
return back()->withInput()->with('error', 'Gagal menyimpan data: ' . $e->getMessage());
}
return response()->json([ return response()->json([
'status' => 'error', 'status' => 'error',
'message' => 'Gagal menyimpan data: ' . $e->getMessage() 'message' => 'Gagal menyimpan data: ' . $e->getMessage()
@@ -4,38 +4,40 @@ namespace App\Http\Controllers\Web\Produktivitas;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Enums\Role; use App\Enums\Role;
use App\Models\Map\Lahan;
use App\Models\Map\Panen;
use App\Models\Map\PanenTanaman;
use App\Models\Pertanian\Komoditas; use App\Models\Pertanian\Komoditas;
use App\Models\Pertanian\Lahan;
use App\Models\Pertanian\Produksi;
use App\Models\Profile; use App\Models\Profile;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
class ProduksiController extends Controller class ProduksiController extends Controller
{ {
public function index(Request $request) public function index(Request $request)
{ {
$query = Produksi::with(['profile', 'lahan', 'komoditas']) $query = Panen::with(['petani', 'lahan', 'panenTanaman'])
->orderBy('harvest_date', 'desc')
->orderBy('created_at', 'desc'); ->orderBy('created_at', 'desc');
if ($request->filled('search')) { if ($request->filled('search')) {
$query->where(function ($q) use ($request) { $query->where(function ($q) use ($request) {
$search = '%' . $request->search . '%'; $search = '%' . $request->search . '%';
$q->where('kode_produksi', 'like', $search) $q->where('title', 'like', $search)
->orWhere('periode', 'like', $search) ->orWhere('notes', 'like', $search)
->orWhereHas('profile', fn ($profile) => $profile->where('nama', 'like', $search)) ->orWhereHas('petani', fn ($profile) => $profile->where('nama', 'like', $search))
->orWhereHas('lahan', fn ($lahan) => $lahan->where('nama', 'like', $search)) ->orWhereHas('lahan', fn ($lahan) => $lahan->where('nama', 'like', $search))
->orWhereHas('komoditas', fn ($komoditas) => $komoditas->where('nama', 'like', $search)); ->orWhereHas('panenTanaman', fn ($detail) => $detail->where('commodity_name', 'like', $search));
}); });
} }
if ($request->filled('status_panen')) { if ($request->filled('komoditas')) {
$query->where('status_panen', $request->status_panen); $query->whereHas('panenTanaman', function ($detail) use ($request) {
} $detail->where('commodity_name', $request->komoditas);
});
if ($request->filled('komoditas_id')) {
$query->where('komoditas_id', $request->komoditas_id);
} }
$produksi = $query->paginate($request->per_page ?? 10); $produksi = $query->paginate($request->per_page ?? 10);
@@ -57,24 +59,28 @@ class ProduksiController extends Controller
return back()->withErrors($validator)->withInput(); return back()->withErrors($validator)->withInput();
} }
Produksi::create($this->payload($request) + [ DB::transaction(function () use ($request) {
$panen = Panen::create($this->panenPayload($request) + [
'created_by' => auth()->id(), 'created_by' => auth()->id(),
'updated_by' => auth()->id(), 'updated_by' => auth()->id(),
]); ]);
$this->savePanenDetail($panen, $request);
});
return redirect()->route('produksi.index')->with('success', 'Data hasil panen berhasil ditambahkan.'); return redirect()->route('produksi.index')->with('success', 'Data hasil panen berhasil ditambahkan.');
} }
public function show($id) public function show($id)
{ {
$produksi = Produksi::with(['profile', 'lahan', 'komoditas'])->findOrFail($id); $produksi = Panen::with(['petani', 'lahan', 'panenTanaman'])->findOrFail($id);
return view('produktivitas.produksi.view', compact('produksi')); return view('produktivitas.produksi.view', compact('produksi'));
} }
public function edit($id) public function edit($id)
{ {
$produksi = Produksi::findOrFail($id); $produksi = Panen::with('panenTanaman')->findOrFail($id);
return view('produktivitas.produksi.edit', $this->formData() + compact('produksi')); return view('produktivitas.produksi.edit', $this->formData() + compact('produksi'));
} }
@@ -87,19 +93,24 @@ class ProduksiController extends Controller
return back()->withErrors($validator)->withInput(); return back()->withErrors($validator)->withInput();
} }
$produksi = Produksi::findOrFail($id); DB::transaction(function () use ($request, $id) {
$produksi->update($this->payload($request) + [ $panen = Panen::findOrFail($id);
$panen->update($this->panenPayload($request) + [
'updated_by' => auth()->id(), 'updated_by' => auth()->id(),
]); ]);
$this->savePanenDetail($panen, $request);
});
return redirect()->route('produksi.index')->with('success', 'Data hasil panen berhasil diperbarui.'); return redirect()->route('produksi.index')->with('success', 'Data hasil panen berhasil diperbarui.');
} }
public function destroy($id) public function destroy($id)
{ {
$produksi = Produksi::findOrFail($id); $panen = Panen::findOrFail($id);
$produksi->update(['deleted_by' => auth()->id()]); $panen->panenTanaman()->delete();
$produksi->delete(); $panen->update(['deleted_by' => auth()->id()]);
$panen->delete();
return response()->json(['status' => 'success', 'message' => 'Data hasil panen berhasil dihapus.']); return response()->json(['status' => 'success', 'message' => 'Data hasil panen berhasil dihapus.']);
} }
@@ -108,9 +119,7 @@ class ProduksiController extends Controller
{ {
return [ return [
'profiles' => Profile::where('role', Role::PETANI->value)->orderBy('nama')->get(), 'profiles' => Profile::where('role', Role::PETANI->value)->orderBy('nama')->get(),
'lahan' => Lahan::whereHas('profile', function ($query) { 'lahan' => Lahan::whereNotNull('profile_id')->orderBy('nama')->get(),
$query->where('role', Role::PETANI->value);
})->orderBy('nama')->get(),
'komoditas' => Komoditas::orderBy('nama')->get(), 'komoditas' => Komoditas::orderBy('nama')->get(),
]; ];
} }
@@ -118,47 +127,56 @@ class ProduksiController extends Controller
private function validator(Request $request) private function validator(Request $request)
{ {
return Validator::make($request->all(), [ return Validator::make($request->all(), [
'kode_produksi' => ['nullable', 'string', 'max:255'], 'farmer_id' => [
'profile_id' => [
'required', 'required',
Rule::exists('profiles', 'id')->where('role', Role::PETANI->value), Rule::exists('profiles', 'id')->where('role', Role::PETANI->value),
], ],
'lahan_id' => [ 'land_id' => [
'required', 'required',
Rule::exists('map_lahan', 'id')->where('profile_id', $request->profile_id), Rule::exists('map_lahan', 'id')->where('profile_id', $request->farmer_id),
], ],
'komoditas_id' => ['required', 'exists:master_komoditas,id'], 'commodity_name' => ['required', 'string', 'max:255'],
'periode' => ['nullable', 'string', 'max:255'], 'harvest_date' => ['required', 'date'],
'tanggal_panen' => ['required', 'date'], 'weight_kg' => ['required', 'numeric', 'min:0'],
'luas_tanam' => ['nullable', 'numeric', 'min:0'], 'satuan' => ['required', 'in:kg,kuintal,ton'],
'luas_panen' => ['nullable', 'numeric', 'min:0'], 'land_description' => ['nullable', 'string'],
'jumlah_panen' => ['required', 'numeric', 'min:0'], 'notes' => ['nullable', 'string'],
'satuan' => ['required', 'string', 'max:20'],
'status_panen' => ['nullable', 'in:panen_sebagian,selesai'],
'catatan' => ['nullable', 'string'],
]); ]);
} }
private function payload(Request $request): array private function panenPayload(Request $request): array
{ {
$luasPanen = (float) $request->luas_panen;
$jumlahPanen = (float) $request->jumlah_panen;
return [ return [
'kode_produksi' => $request->kode_produksi, 'uid' => $request->uid ?: 'PN-' . Str::uuid(),
'profile_id' => $request->profile_id, 'title' => $request->title ?: 'Panen ' . $request->commodity_name,
'lahan_id' => $request->lahan_id, 'land_id' => $request->land_id,
'tanaman_id' => null, 'farmer_id' => $request->farmer_id,
'komoditas_id' => $request->komoditas_id, 'land_description' => $request->land_description,
'periode' => $request->periode, 'harvest_date' => $request->harvest_date,
'tanggal_panen' => $request->tanggal_panen, 'notes' => $request->notes,
'luas_tanam' => $request->luas_tanam, 'sync_status' => 'synced',
'luas_panen' => $request->luas_panen,
'jumlah_panen' => $request->jumlah_panen,
'satuan' => $request->satuan,
'produktivitas' => $luasPanen > 0 ? round($jumlahPanen / $luasPanen, 2) : null,
'status_panen' => $request->status_panen ?? 'selesai',
'catatan' => $request->catatan,
]; ];
} }
private function savePanenDetail(Panen $panen, Request $request): void
{
$detail = $panen->panenTanaman()->first() ?: new PanenTanaman(['panen_id' => $panen->id]);
$detail->fill([
'panen_id' => $panen->id,
'tanaman_id' => null,
'commodity_name' => $request->commodity_name,
'weight_kg' => $this->toKilograms((float) $request->weight_kg, $request->satuan),
'sync_status' => 'synced',
]);
$detail->save();
}
private function toKilograms(float $value, string $unit): float
{
return match ($unit) {
'ton' => $value * 1000,
'kuintal' => $value * 100,
default => $value,
};
}
} }
+3
View File
@@ -29,6 +29,9 @@ class Panen extends Model
'harvest_date', 'harvest_date',
'notes', 'notes',
'sync_status', 'sync_status',
'created_by',
'updated_by',
'deleted_by',
]; ];
protected $casts = [ protected $casts = [
@@ -15,10 +15,10 @@ return new class extends Migration
$bluePrint->id(); $bluePrint->id();
$bluePrint->foreignId('panen_id') $bluePrint->foreignId('panen_id')
->constrained('panen') ->constrained('map_panen')
->onDelete('cascade'); ->onDelete('cascade');
$bluePrint->unsignedBigInteger('tanaman_id'); $bluePrint->unsignedBigInteger('tanaman_id')->nullable();
$bluePrint->string('commodity_name'); $bluePrint->string('commodity_name');
$bluePrint->string('sync_status', 50)->nullable()->default('synced'); $bluePrint->string('sync_status', 50)->nullable()->default('synced');
$bluePrint->decimal('weight_kg', 10, 2); // Menggunakan decimal agar mendukung angka pecahan (misal: 10.5 kg) $bluePrint->decimal('weight_kg', 10, 2); // Menggunakan decimal agar mendukung angka pecahan (misal: 10.5 kg)
@@ -33,6 +33,6 @@ return new class extends Migration
*/ */
public function down(): void public function down(): void
{ {
Schema::dropIfExists('panen_tanamen'); Schema::dropIfExists('panen_tanaman');
} }
}; };
+266 -36
View File
@@ -1,56 +1,286 @@
<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasAddUser" aria-labelledby="offcanvasAddUserLabel"> @extends('layout.main')
<div class="offcanvas-header border-bottom">
<h5 id="offcanvasAddUserLabel" class="offcanvas-title">Tambah User Baru</h5> @section('content')
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button> <div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4 d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">Tambah User Baru</h5>
<a href="{{ route('users.index') }}" class="btn btn-sm btn-label-secondary">
<i class="ti tabler-arrow-left me-1"></i> Kembali
</a>
</div> </div>
<div class="offcanvas-body mx-0 flex-grow-0 p-6 h-100">
<form class="add-new-user pt-0" id="formAddUser" action="{{ route('users.store') }}" method="POST"> <div class="card-body">
@if(session('error'))
<div class="alert alert-danger alert-dismissible" role="alert">
{{ session('error') }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
@endif
<form id="formAddUser" action="{{ route('users.store') }}" method="POST" enctype="multipart/form-data">
@csrf @csrf
<div class="mb-4">
<label class="form-label" for="add-user-fullname">Nama Lengkap</label> <h6 class="mb-3">Informasi Akun</h6>
<input type="text" class="form-control" id="add-user-fullname" placeholder="John Doe" name="name" required /> <div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-profile-nama">Nama Lengkap<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('nama') is-invalid @enderror" id="add-profile-nama" name="nama" value="{{ old('nama') }}" />
@error('nama')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div> </div>
<div class="mb-4"> <div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-user-username">Nama akun</label> <label class="form-label" for="add-profile-email">Email<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="add-user-username" placeholder="john" name="username" required /> <input type="email" class="form-control @error('email') is-invalid @enderror" id="add-profile-email" name="email" value="{{ old('email') }}" />
@error('email')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div> </div>
<div class="mb-4">
<label class="form-label" for="add-user-email">Email</label>
<input type="email" id="add-user-email" class="form-control" placeholder="john.doe@example.com" name="email" required />
</div> </div>
<div class="mb-4">
<label class="form-label" for="add-user-role">User Role</label> <div class="row">
<select id="add-user-role" class="form-select" name="role" required> <div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-profile-username">Nama Akun<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('username') is-invalid @enderror" id="add-profile-username" name="username" value="{{ old('username') }}" />
@error('username')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-profile-role">Role<span class="text-danger">*</span></label>
<select id="add-profile-role" name="role" class="select2 form-select @error('role') is-invalid @enderror" data-placeholder="Pilih Role">
<option value="">Pilih Role</option> <option value="">Pilih Role</option>
@foreach($roles as $roleEnum) @foreach($roles as $roleEnum)
<option value="{{ $roleEnum->value }}">{{ ucfirst(str_replace('_', ' ', $roleEnum->value)) }}</option> <option value="{{ $roleEnum->value }}" {{ old('role', \App\Enums\Role::PETANI->value) === $roleEnum->value ? 'selected' : '' }}>
{{ ucfirst(str_replace('_', ' ', $roleEnum->value)) }}
</option>
@endforeach
</select>
@error('role')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-profile-telepon">No. Telepon<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('telepon') is-invalid @enderror" id="add-profile-telepon" name="telepon" value="{{ old('telepon') }}" />
@error('telepon')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-6 mb-4 form-control-validation form-password-toggle">
<label class="form-label" for="add-profile-password">Password<span class="text-danger">*</span></label>
<div class="input-group input-group-merge">
<input type="password" id="add-profile-password" name="password" class="form-control @error('password') is-invalid @enderror" />
<button type="button" class="input-group-text cursor-pointer password-toggle" aria-label="Lihat password">
<i class="ti tabler-eye-off"></i>
</button>
</div>
@error('password')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div>
<div class="col-md-6 mb-4 form-control-validation form-password-toggle">
<label class="form-label" for="add-profile-password-confirm">Konfirmasi Password<span class="text-danger">*</span></label>
<div class="input-group input-group-merge">
<input type="password" id="add-profile-password-confirm" name="password_confirmation" class="form-control" />
<button type="button" class="input-group-text cursor-pointer password-toggle" aria-label="Lihat konfirmasi password">
<i class="ti tabler-eye-off"></i>
</button>
</div>
</div>
</div>
<hr class="my-4">
<h6 class="mb-3">Lokasi & Alamat</h6>
<div class="row">
<div class="col-md-6 mb-4">
<label class="form-label" for="add-profile-provinsi">Provinsi</label>
<select id="add-profile-provinsi" class="select2 form-select" data-placeholder="Pilih Provinsi">
<option value="">Pilih Provinsi</option>
@foreach($provinsi as $prov)
<option value="{{ $prov->id }}">{{ $prov->nama }}</option>
@endforeach @endforeach
</select> </select>
</div> </div>
<div class="mb-4 form-password-toggle">
<label class="form-label" for="add-user-password">Password</label> <div class="col-md-6 mb-4">
<div class="input-group input-group-merge"> <label class="form-label" for="add-profile-kabupaten">Kabupaten/Kota</label>
<input type="password" id="add-user-password" name="password" class="form-control" placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;" required /> <select id="add-profile-kabupaten" class="select2 form-select" data-placeholder="Pilih Kabupaten/Kota">
<span class="input-group-text cursor-pointer" onclick="togglePassword(this)"> <option value="">Pilih Kabupaten/Kota</option>
<i class="ti tabler-eye-off"></i> </select>
</span>
</div> </div>
</div> </div>
<div class="mb-4 form-password-toggle"> <div class="row">
<label class="form-label" for="add-user-password-confirm">Konfirmasi Password</label> <div class="col-md-6 mb-4">
<div class="input-group input-group-merge"> <label class="form-label" for="add-profile-kecamatan">Kecamatan</label>
<input type="password" id="add-user-password-confirm" name="password_confirmation" class="form-control" placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;" required /> <select id="add-profile-kecamatan" class="select2 form-select" data-placeholder="Pilih Kecamatan">
<span class="input-group-text cursor-pointer" onclick="togglePassword(this)"> <option value="">Pilih Kecamatan</option>
<i class="ti tabler-eye-off"></i> </select>
</span> </div>
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-profile-desa">Desa/Kelurahan<span class="text-danger">*</span></label>
<select id="add-profile-desa" name="desa_kelurahan_id" class="select2 form-select @error('desa_kelurahan_id') is-invalid @enderror" data-placeholder="Pilih Desa/Kelurahan">
<option value="">Pilih Desa/Kelurahan</option>
</select>
@error('desa_kelurahan_id')<div class="invalid-feedback d-block">{{ $message }}</div>@enderror
</div> </div>
</div> </div>
<div class="mt-6 d-flex gap-3"> <div class="mb-4">
<button type="submit" class="btn btn-primary flex-grow-1 data-submit">Simpan</button> <label class="form-label" for="add-profile-alamat">Alamat Lengkap</label>
<button type="reset" class="btn btn-label-secondary flex-grow-1" data-bs-dismiss="offcanvas">Batal</button> <textarea class="form-control" id="add-profile-alamat" name="alamat" rows="2">{{ old('alamat') }}</textarea>
</div>
<hr class="my-4">
<h6 class="mb-3">Dokumen Pribadi</h6>
<div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-profile-no-ktp">NIK (KTP)</label>
<input type="text" class="form-control @error('ktp') is-invalid @enderror" id="add-profile-no-ktp" name="ktp" value="{{ old('ktp') }}" />
@error('ktp')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-profile-no-kk">No. KK</label>
<input type="text" class="form-control @error('kk') is-invalid @enderror" id="add-profile-no-kk" name="kk" value="{{ old('kk') }}" />
@error('kk')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-profile-file-ktp">File KTP</label>
<input type="file" class="form-control @error('file_ktp') is-invalid @enderror" id="add-profile-file-ktp" name="file_ktp" accept="image/*,.pdf" />
@error('file_ktp')<div class="invalid-feedback">{{ $message }}</div>@enderror
<div id="add-preview-container-ktp" class="mt-3 d-none">
<img id="add-preview-image-ktp" src="" alt="Preview KTP" class="img-thumbnail d-none" style="width: 100%; max-height: 250px; object-fit: contain; background-color: #f8f9fa;">
<div id="add-preview-pdf-ktp" class="badge bg-label-danger p-2 w-100 d-none"><i class="ti tabler-file-type-pdf ti-sm me-1"></i> Dokumen PDF (Baru Terpilih)</div>
</div>
</div>
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-profile-file-kk">File KK</label>
<input type="file" class="form-control @error('file_kk') is-invalid @enderror" id="add-profile-file-kk" name="file_kk" accept="image/*,.pdf" />
@error('file_kk')<div class="invalid-feedback">{{ $message }}</div>@enderror
<div id="add-preview-container-kk" class="mt-3 d-none">
<img id="add-preview-image-kk" src="" alt="Preview KK" class="img-thumbnail d-none" style="width: 100%; max-height: 250px; object-fit: contain; background-color: #f8f9fa;">
<div id="add-preview-pdf-kk" class="badge bg-label-danger p-2 w-100 d-none"><i class="ti tabler-file-type-pdf ti-sm me-1"></i> Dokumen PDF (Baru Terpilih)</div>
</div>
</div>
</div>
<div class="mt-4 text-end">
<a href="{{ route('users.index') }}" class="btn btn-label-secondary me-2">Batal</a>
<button type="submit" class="btn btn-primary">Simpan Perubahan</button>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$('.select2').select2();
$(document).on('click', '.password-toggle', function () {
const input = this.closest('.input-group').querySelector('input');
const icon = this.querySelector('i');
const isHidden = input.type === 'password';
input.type = isHidden ? 'text' : 'password';
icon.className = isHidden ? 'ti tabler-eye' : 'ti tabler-eye-off';
this.setAttribute('aria-label', isHidden ? 'Sembunyikan password' : 'Lihat password');
});
function handleFilePreview(inputId, containerId, imageId, pdfId) {
$(`#${inputId}`).on('change', function(event) {
const file = event.target.files[0];
const $container = $(`#${containerId}`);
const $image = $(`#${imageId}`);
const $pdf = $(`#${pdfId}`);
if (!file) {
$container.addClass('d-none');
return;
}
$container.removeClass('d-none');
if (file.type.match('image.*')) {
const reader = new FileReader();
reader.onload = function(e) {
$image.attr('src', e.target.result).removeClass('d-none');
$pdf.addClass('d-none');
};
reader.readAsDataURL(file);
} else if (file.type === 'application/pdf') {
$image.addClass('d-none').attr('src', '');
$pdf.removeClass('d-none');
} else {
$container.addClass('d-none');
}
});
}
function setupCascadingDropdown() {
$('#add-profile-provinsi').on('change', function () {
const provinsiId = $(this).val();
const $kabupaten = $('#add-profile-kabupaten');
const $kecamatan = $('#add-profile-kecamatan');
const $desa = $('#add-profile-desa');
$kabupaten.empty().append('<option value="">Pilih Kabupaten/Kota</option>').trigger('change');
$kecamatan.empty().append('<option value="">Pilih Kecamatan</option>').trigger('change');
$desa.empty().append('<option value="">Pilih Desa/Kelurahan</option>').trigger('change');
if (provinsiId) {
$.get(`/kabupatenkotabyprovinsi/${provinsiId}`, function (res) {
const dataList = Array.isArray(res) ? res : (res.data || []);
$.each(dataList, function (key, val) {
$kabupaten.append(`<option value="${val.id}">${val.nama}</option>`);
});
});
}
});
$('#add-profile-kabupaten').on('change', function () {
const kabupatenId = $(this).val();
const $kecamatan = $('#add-profile-kecamatan');
const $desa = $('#add-profile-desa');
$kecamatan.empty().append('<option value="">Pilih Kecamatan</option>').trigger('change');
$desa.empty().append('<option value="">Pilih Desa/Kelurahan</option>').trigger('change');
if (kabupatenId) {
$.get(`/kecamatanbykabupatenkota/${kabupatenId}`, function (res) {
const dataList = Array.isArray(res) ? res : (res.data || []);
$.each(dataList, function (key, val) {
$kecamatan.append(`<option value="${val.id}">${val.nama}</option>`);
});
});
}
});
$('#add-profile-kecamatan').on('change', function () {
const kecamatanId = $(this).val();
const $desa = $('#add-profile-desa');
$desa.empty().append('<option value="">Pilih Desa/Kelurahan</option>').trigger('change');
if (kecamatanId) {
$.get(`/desakelurahanbykecamatan/${kecamatanId}`, function (res) {
const dataList = Array.isArray(res) ? res : (res.data || []);
$.each(dataList, function (key, val) {
$desa.append(`<option value="${val.id}">${val.nama}</option>`);
});
});
}
});
}
handleFilePreview('add-profile-file-ktp', 'add-preview-container-ktp', 'add-preview-image-ktp', 'add-preview-pdf-ktp');
handleFilePreview('add-profile-file-kk', 'add-preview-container-kk', 'add-preview-image-kk', 'add-preview-pdf-kk');
setupCascadingDropdown();
});
</script>
@endpush
@@ -85,9 +85,9 @@
<div class="card"> <div class="card">
<div class="card-header border-bottom d-flex justify-content-between align-items-center"> <div class="card-header border-bottom d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">Daftar Pengguna</h5> <h5 class="card-title mb-0">Daftar Pengguna</h5>
<button class="btn btn-sm btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasAddUser"> <a class="btn btn-sm btn-primary" href="{{ route('users.create') }}">
<i class="ti tabler-plus me-1"></i> Add New User <i class="ti tabler-plus me-1"></i> Tambah User Baru
</button> </a>
</div> </div>
<form method="GET" action="{{ route('users.index') }}" id="filterForm"> <form method="GET" action="{{ route('users.index') }}" id="filterForm">
@@ -204,7 +204,6 @@
{{ $users->appends(request()->query())->links('pagination::bootstrap-5') }} {{ $users->appends(request()->query())->links('pagination::bootstrap-5') }}
</div> </div>
</div> </div>
@include('konfigurasi.user.add')
@include('konfigurasi.user.edit') @include('konfigurasi.user.edit')
</div> </div>
@endsection @endsection
@@ -369,77 +368,5 @@
}); });
}); });
}); });
document.addEventListener("DOMContentLoaded", function() {
function togglePassword(element) {
const input = element.parentElement.querySelector('input');
const icon = element.querySelector('i');
if (input.type === 'password') {
input.type = 'text';
icon.className = 'ti ti-eye tabler-eye';
} else {
input.type = 'password';
icon.className = 'ti ti-eye-off tabler-eye-off';
}
}
const formAddUser = document.getElementById('formAddUser');
const offcanvasElement = document.getElementById('offcanvasAddUser');
if (formAddUser && offcanvasElement) {
formAddUser.addEventListener('submit', function(e) {
e.preventDefault();
let formData = new FormData(this);
let submitBtn = this.querySelector('button[type="submit"]');
submitBtn.disabled = true;
let originalText = submitBtn.innerHTML;
submitBtn.innerHTML = 'Menyimpan...';
fetch(this.action, {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Accept': 'application/json'
}
})
.then(response => response.json())
.then(data => {
submitBtn.disabled = false;
submitBtn.innerHTML = originalText;
if (data.status === 'success') {
let bsOffcanvas = bootstrap.Offcanvas.getInstance(offcanvasElement) || new bootstrap.Offcanvas(offcanvasElement);
bsOffcanvas.hide();
Swal.fire({
icon: 'success',
title: 'Berhasil!',
text: data.message,
showConfirmButton: false,
timer: 1500
}).then(() => {
window.location.reload();
});
} else {
let errorMsg = data.message || 'Terjadi kesalahan.';
if (data.errors) {
errorMsg = Object.values(data.errors).map(err => err.join(', ')).join('<br>');
}
Swal.fire({ icon: 'error', title: 'Gagal!', html: errorMsg });
}
})
.catch(error => {
submitBtn.disabled = false;
submitBtn.innerHTML = originalText;
Swal.fire({ icon: 'error', title: 'Error', text: 'Koneksi bermasalah atau terjadi kesalahan server.' });
});
});
}
});
</script> </script>
@endpush @endpush
@@ -4,43 +4,47 @@
@method('PUT') @method('PUT')
@endif @endif
@php
$detailPanen = isset($produksi) ? $produksi->panenTanaman->first() : null;
@endphp
<div class="row"> <div class="row">
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label class="form-label">Petani <span class="text-danger">*</span></label> <label class="form-label">Petani <span class="text-danger">*</span></label>
<select name="profile_id" id="profile_id" class="form-select @error('profile_id') is-invalid @enderror" required> <select name="farmer_id" id="profile_id" class="form-select @error('farmer_id') is-invalid @enderror" required>
<option value="">Pilih Petani</option> <option value="">Pilih Petani</option>
@foreach($profiles as $profile) @foreach($profiles as $profile)
<option value="{{ $profile->id }}" {{ old('profile_id', $produksi->profile_id ?? '') == $profile->id ? 'selected' : '' }}>{{ $profile->nama }}</option> <option value="{{ $profile->id }}" {{ old('farmer_id', $produksi->farmer_id ?? '') == $profile->id ? 'selected' : '' }}>{{ $profile->nama }}</option>
@endforeach @endforeach
</select> </select>
@error('profile_id')<div class="invalid-feedback">{{ $message }}</div>@enderror @error('farmer_id')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div> </div>
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label class="form-label">Lahan <span class="text-danger">*</span></label> <label class="form-label">Lahan <span class="text-danger">*</span></label>
<select name="lahan_id" id="lahan_id" class="form-select @error('lahan_id') is-invalid @enderror" required disabled> <select name="land_id" id="lahan_id" class="form-select @error('land_id') is-invalid @enderror" required disabled>
<option value="">Pilih Petani terlebih dahulu</option> <option value="">Pilih Petani terlebih dahulu</option>
</select> </select>
@error('lahan_id')<div class="invalid-feedback">{{ $message }}</div>@enderror @error('land_id')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div> </div>
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label class="form-label">Komoditas Hasil Panen <span class="text-danger">*</span></label> <label class="form-label">Komoditas Hasil Panen <span class="text-danger">*</span></label>
<select name="komoditas_id" class="form-select @error('komoditas_id') is-invalid @enderror" required> <select name="commodity_name" class="form-select @error('commodity_name') is-invalid @enderror" required>
<option value="">Pilih Komoditas</option> <option value="">Pilih Komoditas</option>
@foreach($komoditas as $item) @foreach($komoditas as $item)
<option value="{{ $item->id }}" {{ old('komoditas_id', $produksi->komoditas_id ?? '') == $item->id ? 'selected' : '' }}>{{ $item->nama }}</option> <option value="{{ $item->nama }}" {{ old('commodity_name', $detailPanen->commodity_name ?? '') == $item->nama ? 'selected' : '' }}>{{ $item->nama }}</option>
@endforeach @endforeach
</select> </select>
@error('komoditas_id')<div class="invalid-feedback">{{ $message }}</div>@enderror @error('commodity_name')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div> </div>
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label class="form-label">Tanggal Panen <span class="text-danger">*</span></label> <label class="form-label">Tanggal Panen <span class="text-danger">*</span></label>
<input type="date" name="tanggal_panen" class="form-control @error('tanggal_panen') is-invalid @enderror" value="{{ old('tanggal_panen', isset($produksi) && $produksi->tanggal_panen ? $produksi->tanggal_panen->format('Y-m-d') : '') }}" required> <input type="date" name="harvest_date" class="form-control @error('harvest_date') is-invalid @enderror" value="{{ old('harvest_date', isset($produksi) && $produksi->harvest_date ? $produksi->harvest_date->format('Y-m-d') : '') }}" required>
@error('tanggal_panen')<div class="invalid-feedback">{{ $message }}</div>@enderror @error('harvest_date')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div> </div>
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label class="form-label">Jumlah Hasil Panen <span class="text-danger">*</span></label> <label class="form-label">Jumlah Hasil Panen <span class="text-danger">*</span></label>
<input type="number" step="0.01" name="jumlah_panen" class="form-control @error('jumlah_panen') is-invalid @enderror" value="{{ old('jumlah_panen', $produksi->jumlah_panen ?? '') }}" required> <input type="number" step="0.01" name="weight_kg" class="form-control @error('weight_kg') is-invalid @enderror" value="{{ old('weight_kg', $detailPanen->weight_kg ?? '') }}" required>
@error('jumlah_panen')<div class="invalid-feedback">{{ $message }}</div>@enderror @error('weight_kg')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div> </div>
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label class="form-label">Satuan Panen <span class="text-danger">*</span></label> <label class="form-label">Satuan Panen <span class="text-danger">*</span></label>
@@ -52,33 +56,19 @@
@error('satuan')<div class="invalid-feedback">{{ $message }}</div>@enderror @error('satuan')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div> </div>
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label class="form-label">Luas Tanam (ha)</label> <label class="form-label">Judul Panen</label>
<input type="number" step="0.01" name="luas_tanam" class="form-control @error('luas_tanam') is-invalid @enderror" value="{{ old('luas_tanam', $produksi->luas_tanam ?? '') }}"> <input type="text" name="title" class="form-control @error('title') is-invalid @enderror" value="{{ old('title', $produksi->title ?? '') }}" placeholder="Contoh: Panen Padi Juni 2026">
@error('luas_tanam')<div class="invalid-feedback">{{ $message }}</div>@enderror @error('title')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div> </div>
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label class="form-label">Luas Panen (ha)</label> <label class="form-label">Kondisi Lahan Saat Panen</label>
<input type="number" step="0.01" name="luas_panen" class="form-control @error('luas_panen') is-invalid @enderror" value="{{ old('luas_panen', $produksi->luas_panen ?? '') }}"> <input type="text" name="land_description" class="form-control @error('land_description') is-invalid @enderror" value="{{ old('land_description', $produksi->land_description ?? '') }}">
@error('luas_panen')<div class="invalid-feedback">{{ $message }}</div>@enderror @error('land_description')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Status Panen <span class="text-danger">*</span></label>
<select name="status_panen" class="form-select @error('status_panen') is-invalid @enderror" required>
@foreach(['selesai' => 'Selesai', 'panen_sebagian' => 'Panen Sebagian'] as $value => $label)
<option value="{{ $value }}" {{ old('status_panen', $produksi->status_panen ?? 'selesai') == $value ? 'selected' : '' }}>{{ $label }}</option>
@endforeach
</select>
@error('status_panen')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Periode Panen</label>
<input type="text" name="periode" class="form-control @error('periode') is-invalid @enderror" value="{{ old('periode', $produksi->periode ?? '') }}" placeholder="Contoh: Musim Tanam I 2026">
@error('periode')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div> </div>
<div class="col-12 mb-3"> <div class="col-12 mb-3">
<label class="form-label">Catatan</label> <label class="form-label">Catatan</label>
<textarea name="catatan" class="form-control @error('catatan') is-invalid @enderror" rows="4" placeholder="Catatan kendala atau informasi tambahan">{{ old('catatan', $produksi->catatan ?? '') }}</textarea> <textarea name="notes" class="form-control @error('notes') is-invalid @enderror" rows="4" placeholder="Catatan kendala atau informasi tambahan">{{ old('notes', $produksi->notes ?? '') }}</textarea>
@error('catatan')<div class="invalid-feedback">{{ $message }}</div>@enderror @error('notes')<div class="invalid-feedback">{{ $message }}</div>@enderror
</div> </div>
</div> </div>
@@ -101,7 +91,7 @@
document.addEventListener('DOMContentLoaded', function () { document.addEventListener('DOMContentLoaded', function () {
const profileSelect = document.getElementById('profile_id'); const profileSelect = document.getElementById('profile_id');
const lahanSelect = document.getElementById('lahan_id'); const lahanSelect = document.getElementById('lahan_id');
const selectedLahanId = "{{ old('lahan_id', $produksi->lahan_id ?? '') }}"; const selectedLahanId = "{{ old('land_id', $produksi->land_id ?? '') }}";
const lahanOptions = @json($lahanOptions); const lahanOptions = @json($lahanOptions);
function renderLahanOptions() { function renderLahanOptions() {
@@ -26,17 +26,12 @@
<label class="ms-2 text-nowrap">entries</label> <label class="ms-2 text-nowrap">entries</label>
</div> </div>
<div class="col-md-auto d-flex gap-2"> <div class="col-md-auto d-flex gap-2">
<select name="komoditas_id" class="form-select form-select-sm w-auto" onchange="this.form.submit()"> <select name="komoditas" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
<option value="">Semua Komoditas</option> <option value="">Semua Komoditas</option>
@foreach($komoditas as $item) @foreach($komoditas as $item)
<option value="{{ $item->id }}" {{ request('komoditas_id') == $item->id ? 'selected' : '' }}>{{ $item->nama }}</option> <option value="{{ $item->nama }}" {{ request('komoditas') == $item->nama ? 'selected' : '' }}>{{ $item->nama }}</option>
@endforeach @endforeach
</select> </select>
<select name="status_panen" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
<option value="">Semua Status</option>
<option value="panen_sebagian" {{ request('status_panen') == 'panen_sebagian' ? 'selected' : '' }}>Panen Sebagian</option>
<option value="selesai" {{ request('status_panen') == 'selesai' ? 'selected' : '' }}>Selesai</option>
</select>
<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 hasil panen..." value="{{ request('search') }}"> <input type="text" name="search" class="form-control" placeholder="Cari hasil panen..." 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>
@@ -55,35 +50,31 @@
<th>Lahan</th> <th>Lahan</th>
<th>Tanggal Panen</th> <th>Tanggal Panen</th>
<th>Hasil Panen</th> <th>Hasil Panen</th>
<th>Produktivitas</th> <th>Judul</th>
<th>Status</th>
<th>Actions</th> <th>Actions</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@forelse($produksi as $index => $item) @forelse($produksi as $index => $item)
@php($detailPanen = $item->panenTanaman->first())
<tr> <tr>
<td>{{ $produksi->firstItem() + $index }}</td> <td>{{ $produksi->firstItem() + $index }}</td>
<td>{{ $item->komoditas->nama ?? '-' }}</td> <td>{{ $detailPanen->commodity_name ?? '-' }}</td>
<td>{{ $item->profile->nama ?? '-' }}</td> <td>{{ $item->petani->nama ?? '-' }}</td>
<td>{{ $item->lahan->nama ?? '-' }}</td> <td>{{ $item->lahan->nama ?? '-' }}</td>
<td>{{ $item->tanggal_panen ? $item->tanggal_panen->format('d-m-Y') : '-' }}</td> <td>{{ $item->harvest_date ? $item->harvest_date->format('d-m-Y') : '-' }}</td>
<td>{{ $item->jumlah_panen ?? '-' }} {{ $item->jumlah_panen ? $item->satuan : '' }}</td> <td>{{ $detailPanen ? $detailPanen->weight_kg . ' kg' : '-' }}</td>
<td>{{ $item->produktivitas ? $item->produktivitas . ' ' . $item->satuan . '/ha' : '-' }}</td> <td>{{ $item->title ?? '-' }}</td>
<td>
@php($statusClass = ['panen_sebagian' => 'warning', 'selesai' => 'success'][$item->status_panen] ?? 'secondary')
<span class="badge bg-label-{{ $statusClass }}">{{ ucwords(str_replace('_', ' ', $item->status_panen)) }}</span>
</td>
<td> <td>
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<a href="{{ route('produksi.edit', $item->id) }}" class="btn btn-icon btn-text-secondary rounded-pill"><i class="ti tabler-edit ti-md"></i></a> <a href="{{ route('produksi.edit', $item->id) }}" class="btn btn-icon btn-text-secondary rounded-pill"><i class="ti tabler-edit ti-md"></i></a>
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $item->id }}" data-nama="{{ $item->komoditas->nama ?? 'Hasil Panen' }}"><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="{{ $item->id }}" data-nama="{{ $detailPanen->commodity_name ?? 'Hasil Panen' }}"><i class="ti tabler-trash ti-md"></i></a>
<a href="{{ route('produksi.show', $item->id) }}" class="btn btn-icon btn-text-secondary rounded-pill"><i class="ti tabler-eye ti-md"></i></a> <a href="{{ route('produksi.show', $item->id) }}" class="btn btn-icon btn-text-secondary rounded-pill"><i class="ti tabler-eye ti-md"></i></a>
</div> </div>
</td> </td>
</tr> </tr>
@empty @empty
<tr><td colspan="9" class="text-center py-4">Tidak ada data hasil panen ditemukan.</td></tr> <tr><td colspan="8" class="text-center py-4">Tidak ada data hasil panen ditemukan.</td></tr>
@endforelse @endforelse
</tbody> </tbody>
</table> </table>
@@ -9,18 +9,16 @@
</div> </div>
<div class="card-body pt-4"> <div class="card-body pt-4">
<div class="row g-3"> <div class="row g-3">
@php($detailPanen = $produksi->panenTanaman->first())
@foreach([ @foreach([
'Komoditas' => $produksi->komoditas->nama ?? '-', 'Judul Panen' => $produksi->title,
'Petani' => $produksi->profile->nama ?? '-', 'Komoditas' => $detailPanen->commodity_name ?? '-',
'Petani' => $produksi->petani->nama ?? '-',
'Lahan' => $produksi->lahan->nama ?? '-', 'Lahan' => $produksi->lahan->nama ?? '-',
'Tanggal Panen' => $produksi->tanggal_panen ? $produksi->tanggal_panen->format('d-m-Y') : '-', 'Tanggal Panen' => $produksi->harvest_date ? $produksi->harvest_date->format('d-m-Y') : '-',
'Jumlah Hasil Panen' => $produksi->jumlah_panen ? $produksi->jumlah_panen . ' ' . $produksi->satuan : '-', 'Jumlah Hasil Panen' => $detailPanen ? $detailPanen->weight_kg . ' kg' : '-',
'Satuan Panen' => $produksi->satuan, 'Kondisi Lahan Saat Panen' => $produksi->land_description,
'Luas Tanam' => $produksi->luas_tanam ? $produksi->luas_tanam . ' ha' : '-', 'Status Sinkronisasi' => $produksi->sync_status,
'Luas Panen' => $produksi->luas_panen ? $produksi->luas_panen . ' ha' : '-',
'Produktivitas' => $produksi->produktivitas ? $produksi->produktivitas . ' ' . $produksi->satuan . '/ha' : '-',
'Status Panen' => ucwords(str_replace('_', ' ', $produksi->status_panen)),
'Periode Panen' => $produksi->periode,
] as $label => $value) ] as $label => $value)
<div class="col-md-4"> <div class="col-md-4">
<label class="form-label text-muted">{{ $label }}</label> <label class="form-label text-muted">{{ $label }}</label>
@@ -29,7 +27,7 @@
@endforeach @endforeach
<div class="col-12"> <div class="col-12">
<label class="form-label text-muted">Catatan</label> <label class="form-label text-muted">Catatan</label>
<div>{{ $produksi->catatan ?? '-' }}</div> <div>{{ $produksi->notes ?? '-' }}</div>
</div> </div>
</div> </div>
</div> </div>