update daftar pengguna
This commit is contained in:
@@ -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()) {
|
||||||
return response()->json(['status' => 'error', 'errors' => $validator->errors()], 422);
|
if ($request->expectsJson()) {
|
||||||
|
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(),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
return response()->json([
|
if ($request->expectsJson()) {
|
||||||
'status' => 'success',
|
return response()->json([
|
||||||
'message' => 'User baru berhasil ditambahkan.'
|
'status' => 'success',
|
||||||
]);
|
'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) {
|
||||||
'created_by' => auth()->id(),
|
$panen = Panen::create($this->panenPayload($request) + [
|
||||||
'updated_by' => auth()->id(),
|
'created_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);
|
||||||
'updated_by' => auth()->id(),
|
$panen->update($this->panenPayload($request) + [
|
||||||
]);
|
'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,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>
|
|
||||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
|
||||||
</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">
|
|
||||||
@csrf
|
|
||||||
<div class="mb-4">
|
|
||||||
<label class="form-label" for="add-user-fullname">Nama Lengkap</label>
|
|
||||||
<input type="text" class="form-control" id="add-user-fullname" placeholder="John Doe" name="name" required />
|
|
||||||
</div>
|
|
||||||
<div class="mb-4">
|
|
||||||
<label class="form-label" for="add-user-username">Nama akun</label>
|
|
||||||
<input type="text" class="form-control" id="add-user-username" placeholder="john" name="username" required />
|
|
||||||
</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 class="mb-4">
|
|
||||||
<label class="form-label" for="add-user-role">User Role</label>
|
|
||||||
<select id="add-user-role" class="form-select" name="role" required>
|
|
||||||
<option value="">Pilih Role</option>
|
|
||||||
@foreach($roles as $roleEnum)
|
|
||||||
<option value="{{ $roleEnum->value }}">{{ ucfirst(str_replace('_', ' ', $roleEnum->value)) }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="mb-4 form-password-toggle">
|
|
||||||
<label class="form-label" for="add-user-password">Password</label>
|
|
||||||
<div class="input-group input-group-merge">
|
|
||||||
<input type="password" id="add-user-password" name="password" class="form-control" placeholder="············" required />
|
|
||||||
<span class="input-group-text cursor-pointer" onclick="togglePassword(this)">
|
|
||||||
<i class="ti tabler-eye-off"></i>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-4 form-password-toggle">
|
@section('content')
|
||||||
<label class="form-label" for="add-user-password-confirm">Konfirmasi Password</label>
|
<div class="container-xxl flex-grow-1 container-p-y">
|
||||||
<div class="input-group input-group-merge">
|
<div class="card">
|
||||||
<input type="password" id="add-user-password-confirm" name="password_confirmation" class="form-control" placeholder="············" required />
|
<div class="card-header border-bottom mb-4 d-flex justify-content-between align-items-center">
|
||||||
<span class="input-group-text cursor-pointer" onclick="togglePassword(this)">
|
<h5 class="card-title mb-0">Tambah User Baru</h5>
|
||||||
<i class="ti tabler-eye-off"></i>
|
<a href="{{ route('users.index') }}" class="btn btn-sm btn-label-secondary">
|
||||||
</span>
|
<i class="ti tabler-arrow-left me-1"></i> Kembali
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6 d-flex gap-3">
|
<div class="card-body">
|
||||||
<button type="submit" class="btn btn-primary flex-grow-1 data-submit">Simpan</button>
|
@if(session('error'))
|
||||||
<button type="reset" class="btn btn-label-secondary flex-grow-1" data-bs-dismiss="offcanvas">Batal</button>
|
<div class="alert alert-danger alert-dismissible" role="alert">
|
||||||
</div>
|
{{ session('error') }}
|
||||||
</form>
|
<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
|
||||||
|
|
||||||
|
<h6 class="mb-3">Informasi Akun</h6>
|
||||||
|
<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 class="col-md-6 mb-4 form-control-validation">
|
||||||
|
<label class="form-label" for="add-profile-email">Email<span class="text-danger">*</span></label>
|
||||||
|
<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="row">
|
||||||
|
<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>
|
||||||
|
@foreach($roles as $roleEnum)
|
||||||
|
<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
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6 mb-4">
|
||||||
|
<label class="form-label" for="add-profile-kabupaten">Kabupaten/Kota</label>
|
||||||
|
<select id="add-profile-kabupaten" class="select2 form-select" data-placeholder="Pilih Kabupaten/Kota">
|
||||||
|
<option value="">Pilih Kabupaten/Kota</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 mb-4">
|
||||||
|
<label class="form-label" for="add-profile-kecamatan">Kecamatan</label>
|
||||||
|
<select id="add-profile-kecamatan" class="select2 form-select" data-placeholder="Pilih Kecamatan">
|
||||||
|
<option value="">Pilih Kecamatan</option>
|
||||||
|
</select>
|
||||||
|
</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 class="mb-4">
|
||||||
|
<label class="form-label" for="add-profile-alamat">Alamat Lengkap</label>
|
||||||
|
<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>
|
||||||
|
</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>
|
||||||
|
|||||||
Reference in New Issue
Block a user