update profile & produktivitas
This commit is contained in:
@@ -5,7 +5,16 @@ namespace App\Http\Controllers\Web\Konfigurasi;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use App\Models\Profile;
|
||||
use App\Models\Pertanian\Lahan;
|
||||
use App\Models\Pertanian\Komoditas;
|
||||
use App\Models\Pertanian\Tanaman;
|
||||
use App\Models\Wilayah\DesaKelurahan;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
@@ -13,9 +22,221 @@ class ProfileController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$userid = auth()->user()->id;
|
||||
$profile = Profile::where('user_id', $userid)->first();
|
||||
$user = auth()->user();
|
||||
$profile = Profile::where('user_id', $user->id)->first();
|
||||
|
||||
$profileId = $profile?->id;
|
||||
$jumlahLahan = $profileId ? Lahan::where('profile_id', $profileId)->count() : 0;
|
||||
$totalLuasLahan = $profileId ? Lahan::where('profile_id', $profileId)->sum('luas_lahan') : 0;
|
||||
$jumlahTanaman = $profileId ? Tanaman::where('profile_id', $profileId)->count() : 0;
|
||||
$jumlahKomoditas = $profileId
|
||||
? Tanaman::where('profile_id', $profileId)->whereNotNull('komoditas_id')->distinct('komoditas_id')->count('komoditas_id')
|
||||
: 0;
|
||||
$problemSummary = $this->getProblemSummary();
|
||||
|
||||
$activities = $this->getProfileActivities($user, $profile);
|
||||
|
||||
$title = 'Profile';
|
||||
return view('konfigurasi.profile.index', compact('title', 'profile'));
|
||||
return view('konfigurasi.profile.index', compact('title', 'profile', 'jumlahKomoditas', 'jumlahLahan', 'totalLuasLahan', 'jumlahTanaman', 'activities', 'problemSummary'));
|
||||
}
|
||||
|
||||
public function security()
|
||||
{
|
||||
$user = auth()->user();
|
||||
$profile = Profile::where('user_id', $user->id)->first();
|
||||
$loginSessions = $this->getLoginSessions($user);
|
||||
$title = 'Keamanan Akun';
|
||||
|
||||
return view('konfigurasi.profile.security', compact('title', 'profile', 'loginSessions'));
|
||||
}
|
||||
|
||||
public function activities()
|
||||
{
|
||||
$user = auth()->user();
|
||||
$profile = Profile::where('user_id', $user->id)->first();
|
||||
|
||||
return response()->json([
|
||||
'activities' => $this->getProfileActivities($user, $profile)->values(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function updatePassword(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'current_password' => ['required', 'current_password'],
|
||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||
], [
|
||||
'current_password.current_password' => 'Password saat ini tidak sesuai.',
|
||||
'password.confirmed' => 'Konfirmasi password baru tidak cocok.',
|
||||
'password.min' => 'Password baru minimal 8 karakter.',
|
||||
]);
|
||||
|
||||
$request->user()->update([
|
||||
'password' => Hash::make($request->password),
|
||||
]);
|
||||
|
||||
return back()->with('security_success', 'Password berhasil diperbarui.');
|
||||
}
|
||||
|
||||
public function logoutDevices(Request $request)
|
||||
{
|
||||
if (Schema::hasTable('sessions')) {
|
||||
DB::table('sessions')
|
||||
->where('user_id', $request->user()->id)
|
||||
->delete();
|
||||
}
|
||||
|
||||
Auth::logout();
|
||||
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
return redirect()->route('login')->with('success', 'Berhasil logout dari semua perangkat.');
|
||||
}
|
||||
|
||||
private function getLoginSessions(User $user)
|
||||
{
|
||||
if (!Schema::hasTable('sessions')) {
|
||||
return collect();
|
||||
}
|
||||
|
||||
return DB::table('sessions')
|
||||
->where('user_id', $user->id)
|
||||
->orderByDesc('last_activity')
|
||||
->limit(5)
|
||||
->get()
|
||||
->map(function ($session) {
|
||||
return (object) [
|
||||
'id' => $session->id,
|
||||
'ip_address' => $session->ip_address,
|
||||
'user_agent' => $session->user_agent,
|
||||
'last_activity' => \Carbon\Carbon::createFromTimestamp($session->last_activity),
|
||||
'is_current' => $session->id === session()->getId(),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
private function getProblemSummary(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'label' => 'User belum diverifikasi',
|
||||
'count' => User::whereNull('email_verified_at')->count(),
|
||||
'icon' => 'tabler-user-exclamation',
|
||||
'color' => 'warning',
|
||||
'url' => route('users.index', ['tab' => 'pending']),
|
||||
],
|
||||
[
|
||||
'label' => 'Profile tanpa user',
|
||||
'count' => Profile::whereNull('user_id')
|
||||
->orWhereDoesntHave('user')
|
||||
->count(),
|
||||
'icon' => 'tabler-id-off',
|
||||
'color' => 'danger',
|
||||
'url' => route('profile.index'),
|
||||
],
|
||||
[
|
||||
'label' => 'Lahan tanpa luas',
|
||||
'count' => Lahan::whereNull('luas_lahan')
|
||||
->orWhere('luas_lahan', '<=', 0)
|
||||
->count(),
|
||||
'icon' => 'tabler-map-off',
|
||||
'color' => 'warning',
|
||||
'url' => route('lahan.index'),
|
||||
],
|
||||
[
|
||||
'label' => 'Tanaman tanpa komoditas',
|
||||
'count' => Tanaman::whereNull('komoditas_id')->count(),
|
||||
'icon' => 'tabler-plant-off',
|
||||
'color' => 'warning',
|
||||
'url' => route('tanaman.index'),
|
||||
],
|
||||
[
|
||||
'label' => 'Wilayah/desa tidak lengkap',
|
||||
'count' => DesaKelurahan::withoutGlobalScopes()
|
||||
->where(function (Builder $query) {
|
||||
$query->whereNull('kode')
|
||||
->orWhere('kode', '')
|
||||
->orWhereNull('nama')
|
||||
->orWhere('nama', '')
|
||||
->orWhereNull('kecamatan_id')
|
||||
->orWhereNull('path');
|
||||
})
|
||||
->count(),
|
||||
'icon' => 'tabler-map-pin-exclamation',
|
||||
'color' => 'info',
|
||||
'url' => route('desakelurahan.index'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private function getProfileActivities(User $user, ?Profile $profile, int $limit = 20)
|
||||
{
|
||||
$sources = [
|
||||
['model' => Profile::class, 'label' => 'Profil', 'name' => 'nama', 'profile_field' => null],
|
||||
['model' => Lahan::class, 'label' => 'Lahan', 'name' => 'nama', 'profile_field' => 'profile_id'],
|
||||
['model' => Tanaman::class, 'label' => 'Tanaman', 'name' => 'nama', 'profile_field' => 'profile_id'],
|
||||
['model' => Komoditas::class, 'label' => 'Komoditas', 'name' => 'nama', 'profile_field' => null],
|
||||
];
|
||||
|
||||
$activities = collect();
|
||||
|
||||
foreach ($sources as $source) {
|
||||
$query = $source['model']::withTrashed();
|
||||
|
||||
$query->where(function ($query) use ($user) {
|
||||
$query->where('created_by', $user->id)
|
||||
->orWhere('updated_by', $user->id)
|
||||
->orWhere('deleted_by', $user->id);
|
||||
});
|
||||
|
||||
$query->where(function (Builder $query) {
|
||||
$query->where('created_at', '>=', now()->subWeeks(2))
|
||||
->orWhere('updated_at', '>=', now()->subWeeks(2))
|
||||
->orWhere('deleted_at', '>=', now()->subWeeks(2));
|
||||
});
|
||||
|
||||
$query->latest('updated_at')
|
||||
->limit($limit)
|
||||
->get()
|
||||
->each(function ($record) use ($activities, $source) {
|
||||
$activities->push($this->formatActivity($record, $source));
|
||||
});
|
||||
}
|
||||
|
||||
return $activities
|
||||
->sortByDesc('sort_time')
|
||||
->take($limit)
|
||||
->values()
|
||||
->map(function ($activity) {
|
||||
unset($activity['sort_time']);
|
||||
return $activity;
|
||||
});
|
||||
}
|
||||
|
||||
private function formatActivity($record, array $source): array
|
||||
{
|
||||
$name = $record->{$source['name']} ?? 'Tanpa nama';
|
||||
$timestamp = $record->created_at;
|
||||
$action = 'Menambahkan';
|
||||
$color = 'success';
|
||||
|
||||
if ($record->deleted_at) {
|
||||
$timestamp = $record->deleted_at;
|
||||
$action = 'Menghapus';
|
||||
$color = 'danger';
|
||||
} elseif ($record->updated_at && $record->created_at && $record->updated_at->gt($record->created_at)) {
|
||||
$timestamp = $record->updated_at;
|
||||
$action = 'Memperbarui';
|
||||
$color = 'primary';
|
||||
}
|
||||
|
||||
return [
|
||||
'title' => "{$action} {$source['label']}",
|
||||
'description' => "{$source['label']} {$name}",
|
||||
'time' => $timestamp ? $timestamp->diffForHumans() : '-',
|
||||
'color' => $color,
|
||||
'sort_time' => $timestamp,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Web\Produktivitas;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Enums\Role;
|
||||
use App\Models\Pertanian\Komoditas;
|
||||
use App\Models\Pertanian\Kualitas;
|
||||
use App\Models\Pertanian\Lahan;
|
||||
use App\Models\Pertanian\Produksi;
|
||||
use App\Models\Profile;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class KualitasController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$query = Kualitas::with(['produksi', 'profile', 'lahan', 'komoditas'])
|
||||
->orderBy('created_at', 'desc');
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$query->where(function ($q) use ($request) {
|
||||
$search = '%' . $request->search . '%';
|
||||
$q->where('grade', 'like', $search)
|
||||
->orWhere('pemeriksa', 'like', $search)
|
||||
->orWhereHas('profile', fn ($profile) => $profile->where('nama', 'like', $search))
|
||||
->orWhereHas('komoditas', fn ($komoditas) => $komoditas->where('nama', 'like', $search))
|
||||
->orWhereHas('produksi', fn ($produksi) => $produksi->where('kode_produksi', 'like', $search));
|
||||
});
|
||||
}
|
||||
|
||||
if ($request->filled('status_kelayakan')) {
|
||||
$query->where('status_kelayakan', $request->status_kelayakan);
|
||||
}
|
||||
|
||||
$kualitas = $query->paginate($request->per_page ?? 10);
|
||||
|
||||
return view('produktivitas.kualitas.index', compact('kualitas'));
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return view('produktivitas.kualitas.add', $this->formData());
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validator = $this->validator($request);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return back()->withErrors($validator)->withInput();
|
||||
}
|
||||
|
||||
Kualitas::create($this->payload($request) + [
|
||||
'created_by' => auth()->id(),
|
||||
'updated_by' => auth()->id(),
|
||||
]);
|
||||
|
||||
return redirect()->route('kualitas.index')->with('success', 'Data kualitas berhasil ditambahkan.');
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$kualitas = Kualitas::with(['produksi', 'profile', 'lahan', 'komoditas'])->findOrFail($id);
|
||||
|
||||
return view('produktivitas.kualitas.view', compact('kualitas'));
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$kualitas = Kualitas::findOrFail($id);
|
||||
|
||||
return view('produktivitas.kualitas.edit', $this->formData() + compact('kualitas'));
|
||||
}
|
||||
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$validator = $this->validator($request);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return back()->withErrors($validator)->withInput();
|
||||
}
|
||||
|
||||
$kualitas = Kualitas::findOrFail($id);
|
||||
$kualitas->update($this->payload($request) + [
|
||||
'updated_by' => auth()->id(),
|
||||
]);
|
||||
|
||||
return redirect()->route('kualitas.index')->with('success', 'Data kualitas berhasil diperbarui.');
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$kualitas = Kualitas::findOrFail($id);
|
||||
$kualitas->update(['deleted_by' => auth()->id()]);
|
||||
$kualitas->delete();
|
||||
|
||||
return response()->json(['status' => 'success', 'message' => 'Data kualitas berhasil dihapus.']);
|
||||
}
|
||||
|
||||
private function formData(): array
|
||||
{
|
||||
return [
|
||||
'produksi' => Produksi::with(['komoditas', 'profile'])->orderBy('created_at', 'desc')->get(),
|
||||
'profiles' => Profile::where('role', Role::PETANI->value)->orderBy('nama')->get(),
|
||||
'lahan' => Lahan::whereHas('profile', function ($query) {
|
||||
$query->where('role', Role::PETANI->value);
|
||||
})->orderBy('nama')->get(),
|
||||
'komoditas' => Komoditas::orderBy('nama')->get(),
|
||||
];
|
||||
}
|
||||
|
||||
private function validator(Request $request)
|
||||
{
|
||||
return Validator::make($request->all(), [
|
||||
'produksi_id' => ['nullable', 'exists:produksi,id'],
|
||||
'profile_id' => [
|
||||
'required',
|
||||
Rule::exists('profiles', 'id')->where('role', Role::PETANI->value),
|
||||
],
|
||||
'lahan_id' => [
|
||||
'required',
|
||||
Rule::exists('map_lahan', 'id')->where('profile_id', $request->profile_id),
|
||||
],
|
||||
'komoditas_id' => ['required', 'exists:master_komoditas,id'],
|
||||
'tanggal_pemeriksaan' => ['nullable', 'date'],
|
||||
'grade' => ['required', 'string', 'max:50'],
|
||||
'kadar_air' => ['nullable', 'numeric', 'min:0'],
|
||||
'berat_bersih' => ['nullable', 'numeric', 'min:0'],
|
||||
'berat_rusak' => ['nullable', 'numeric', 'min:0'],
|
||||
'standar_mutu' => ['nullable', 'string', 'max:255'],
|
||||
'status_kelayakan' => ['required', 'in:layak,perlu_sortir,tidak_layak'],
|
||||
'pemeriksa' => ['nullable', 'string', 'max:255'],
|
||||
'catatan' => ['nullable', 'string'],
|
||||
]);
|
||||
}
|
||||
|
||||
private function payload(Request $request): array
|
||||
{
|
||||
$beratBersih = (float) $request->berat_bersih;
|
||||
$beratRusak = (float) $request->berat_rusak;
|
||||
|
||||
return [
|
||||
'produksi_id' => $request->produksi_id,
|
||||
'profile_id' => $request->profile_id,
|
||||
'lahan_id' => $request->lahan_id,
|
||||
'komoditas_id' => $request->komoditas_id,
|
||||
'tanggal_pemeriksaan' => $request->tanggal_pemeriksaan,
|
||||
'grade' => $request->grade,
|
||||
'kadar_air' => $request->kadar_air,
|
||||
'berat_bersih' => $request->berat_bersih,
|
||||
'berat_rusak' => $request->berat_rusak,
|
||||
'persentase_kerusakan' => $beratBersih > 0 ? round(($beratRusak / $beratBersih) * 100, 2) : null,
|
||||
'standar_mutu' => $request->standar_mutu,
|
||||
'status_kelayakan' => $request->status_kelayakan,
|
||||
'pemeriksa' => $request->pemeriksa,
|
||||
'catatan' => $request->catatan,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Web\Produktivitas;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Enums\Role;
|
||||
use App\Models\Pertanian\Komoditas;
|
||||
use App\Models\Pertanian\Lahan;
|
||||
use App\Models\Pertanian\Produksi;
|
||||
use App\Models\Pertanian\Tanaman;
|
||||
use App\Models\Profile;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class ProduksiController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$query = Produksi::with(['profile', 'lahan', 'tanaman', 'komoditas'])
|
||||
->orderBy('created_at', 'desc');
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$query->where(function ($q) use ($request) {
|
||||
$search = '%' . $request->search . '%';
|
||||
$q->where('kode_produksi', 'like', $search)
|
||||
->orWhere('periode', 'like', $search)
|
||||
->orWhereHas('profile', fn ($profile) => $profile->where('nama', 'like', $search))
|
||||
->orWhereHas('lahan', fn ($lahan) => $lahan->where('nama', 'like', $search))
|
||||
->orWhereHas('komoditas', fn ($komoditas) => $komoditas->where('nama', 'like', $search));
|
||||
});
|
||||
}
|
||||
|
||||
if ($request->filled('status_panen')) {
|
||||
$query->where('status_panen', $request->status_panen);
|
||||
}
|
||||
|
||||
$produksi = $query->paginate($request->per_page ?? 10);
|
||||
|
||||
return view('produktivitas.produksi.index', compact('produksi'));
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return view('produktivitas.produksi.add', $this->formData());
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validator = $this->validator($request);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return back()->withErrors($validator)->withInput();
|
||||
}
|
||||
|
||||
Produksi::create($this->payload($request) + [
|
||||
'created_by' => auth()->id(),
|
||||
'updated_by' => auth()->id(),
|
||||
]);
|
||||
|
||||
return redirect()->route('produksi.index')->with('success', 'Data produksi berhasil ditambahkan.');
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$produksi = Produksi::with(['profile', 'lahan', 'tanaman', 'komoditas', 'kualitas'])->findOrFail($id);
|
||||
|
||||
return view('produktivitas.produksi.view', compact('produksi'));
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$produksi = Produksi::findOrFail($id);
|
||||
|
||||
return view('produktivitas.produksi.edit', $this->formData() + compact('produksi'));
|
||||
}
|
||||
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$validator = $this->validator($request);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return back()->withErrors($validator)->withInput();
|
||||
}
|
||||
|
||||
$produksi = Produksi::findOrFail($id);
|
||||
$produksi->update($this->payload($request) + [
|
||||
'updated_by' => auth()->id(),
|
||||
]);
|
||||
|
||||
return redirect()->route('produksi.index')->with('success', 'Data produksi berhasil diperbarui.');
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$produksi = Produksi::findOrFail($id);
|
||||
$produksi->update(['deleted_by' => auth()->id()]);
|
||||
$produksi->delete();
|
||||
|
||||
return response()->json(['status' => 'success', 'message' => 'Data produksi berhasil dihapus.']);
|
||||
}
|
||||
|
||||
private function formData(): array
|
||||
{
|
||||
return [
|
||||
'profiles' => Profile::where('role', Role::PETANI->value)->orderBy('nama')->get(),
|
||||
'lahan' => Lahan::whereHas('profile', function ($query) {
|
||||
$query->where('role', Role::PETANI->value);
|
||||
})->orderBy('nama')->get(),
|
||||
'tanaman' => Tanaman::with('komoditas')->orderBy('nama')->get(),
|
||||
'komoditas' => Komoditas::orderBy('nama')->get(),
|
||||
];
|
||||
}
|
||||
|
||||
private function validator(Request $request)
|
||||
{
|
||||
return Validator::make($request->all(), [
|
||||
'kode_produksi' => ['nullable', 'string', 'max:255'],
|
||||
'profile_id' => [
|
||||
'required',
|
||||
Rule::exists('profiles', 'id')->where('role', Role::PETANI->value),
|
||||
],
|
||||
'lahan_id' => [
|
||||
'required',
|
||||
Rule::exists('map_lahan', 'id')->where('profile_id', $request->profile_id),
|
||||
],
|
||||
'tanaman_id' => ['nullable', 'exists:map_tanaman,id'],
|
||||
'komoditas_id' => ['required', 'exists:master_komoditas,id'],
|
||||
'periode' => ['nullable', 'string', 'max:255'],
|
||||
'tanggal_panen' => ['nullable', 'date'],
|
||||
'luas_tanam' => ['nullable', 'numeric', 'min:0'],
|
||||
'luas_panen' => ['nullable', 'numeric', 'min:0'],
|
||||
'jumlah_panen' => ['nullable', 'numeric', 'min:0'],
|
||||
'satuan' => ['required', 'string', 'max:20'],
|
||||
'status_panen' => ['required', 'in:belum_panen,panen_sebagian,selesai'],
|
||||
'catatan' => ['nullable', 'string'],
|
||||
]);
|
||||
}
|
||||
|
||||
private function payload(Request $request): array
|
||||
{
|
||||
$luasPanen = (float) $request->luas_panen;
|
||||
$jumlahPanen = (float) $request->jumlah_panen;
|
||||
|
||||
return [
|
||||
'kode_produksi' => $request->kode_produksi,
|
||||
'profile_id' => $request->profile_id,
|
||||
'lahan_id' => $request->lahan_id,
|
||||
'tanaman_id' => $request->tanaman_id,
|
||||
'komoditas_id' => $request->komoditas_id,
|
||||
'periode' => $request->periode,
|
||||
'tanggal_panen' => $request->tanggal_panen,
|
||||
'luas_tanam' => $request->luas_tanam,
|
||||
'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,
|
||||
'catatan' => $request->catatan,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Web\Produktivitas;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Enums\Role;
|
||||
use App\Models\Wilayah\Provinsi;
|
||||
use App\Models\Profile;
|
||||
use App\Models\User;
|
||||
@@ -18,11 +19,15 @@ class ProfileController extends Controller
|
||||
$provinsi = Provinsi::orderBy('nama', 'asc')->get();
|
||||
|
||||
// Query untuk tabel dengan fitur search dan pagination
|
||||
$query = Profile::with('desakelurahan')->orderBy('created_at', 'desc');
|
||||
$query = Profile::with('desakelurahan')
|
||||
->where('role', Role::PETANI->value)
|
||||
->orderBy('created_at', 'desc');
|
||||
|
||||
if ($request->search) {
|
||||
$query->where('nama', 'like', '%' . $request->search . '%')
|
||||
->orWhere('email', 'like', '%' . $request->search . '%');
|
||||
$query->where(function ($query) use ($request) {
|
||||
$query->where('nama', 'like', '%' . $request->search . '%')
|
||||
->orWhere('email', 'like', '%' . $request->search . '%');
|
||||
});
|
||||
}
|
||||
|
||||
$profiles = $query->paginate($request->per_page ?? 10);
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Profile;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Kualitas extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'kualitas';
|
||||
|
||||
protected $fillable = [
|
||||
'produksi_id',
|
||||
'profile_id',
|
||||
'lahan_id',
|
||||
'komoditas_id',
|
||||
'tanggal_pemeriksaan',
|
||||
'grade',
|
||||
'kadar_air',
|
||||
'berat_bersih',
|
||||
'berat_rusak',
|
||||
'persentase_kerusakan',
|
||||
'standar_mutu',
|
||||
'status_kelayakan',
|
||||
'pemeriksa',
|
||||
'catatan',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'deleted_by',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'tanggal_pemeriksaan' => 'date',
|
||||
];
|
||||
|
||||
public function produksi()
|
||||
{
|
||||
return $this->belongsTo(Produksi::class, 'produksi_id');
|
||||
}
|
||||
|
||||
public function profile()
|
||||
{
|
||||
return $this->belongsTo(Profile::class, 'profile_id');
|
||||
}
|
||||
|
||||
public function lahan()
|
||||
{
|
||||
return $this->belongsTo(Lahan::class, 'lahan_id');
|
||||
}
|
||||
|
||||
public function komoditas()
|
||||
{
|
||||
return $this->belongsTo(Komoditas::class, 'komoditas_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Pertanian;
|
||||
|
||||
use App\Models\Profile;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Produksi extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'produksi';
|
||||
|
||||
protected $fillable = [
|
||||
'kode_produksi',
|
||||
'profile_id',
|
||||
'lahan_id',
|
||||
'tanaman_id',
|
||||
'komoditas_id',
|
||||
'periode',
|
||||
'tanggal_panen',
|
||||
'luas_tanam',
|
||||
'luas_panen',
|
||||
'jumlah_panen',
|
||||
'satuan',
|
||||
'produktivitas',
|
||||
'status_panen',
|
||||
'catatan',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'deleted_by',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'tanggal_panen' => 'date',
|
||||
];
|
||||
|
||||
public function profile()
|
||||
{
|
||||
return $this->belongsTo(Profile::class, 'profile_id');
|
||||
}
|
||||
|
||||
public function lahan()
|
||||
{
|
||||
return $this->belongsTo(Lahan::class, 'lahan_id');
|
||||
}
|
||||
|
||||
public function tanaman()
|
||||
{
|
||||
return $this->belongsTo(Tanaman::class, 'tanaman_id');
|
||||
}
|
||||
|
||||
public function komoditas()
|
||||
{
|
||||
return $this->belongsTo(Komoditas::class, 'komoditas_id');
|
||||
}
|
||||
|
||||
public function kualitas()
|
||||
{
|
||||
return $this->hasMany(Kualitas::class, 'produksi_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('produksi', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('kode_produksi')->nullable();
|
||||
$table->foreignId('profile_id')->nullable()->constrained('profiles')->onDelete('set null');
|
||||
$table->foreignId('lahan_id')->nullable()->constrained('map_lahan')->onDelete('set null');
|
||||
$table->foreignId('tanaman_id')->nullable()->constrained('map_tanaman')->onDelete('set null');
|
||||
$table->foreignId('komoditas_id')->nullable()->constrained('master_komoditas')->onDelete('set null');
|
||||
$table->string('periode')->nullable();
|
||||
$table->date('tanggal_panen')->nullable();
|
||||
$table->decimal('luas_tanam', 12, 2)->nullable();
|
||||
$table->decimal('luas_panen', 12, 2)->nullable();
|
||||
$table->decimal('jumlah_panen', 12, 2)->nullable();
|
||||
$table->string('satuan', 20)->default('kg');
|
||||
$table->decimal('produktivitas', 12, 2)->nullable();
|
||||
$table->string('status_panen')->default('belum_panen');
|
||||
$table->text('catatan')->nullable();
|
||||
$table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null');
|
||||
$table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null');
|
||||
$table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('produksi');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('kualitas', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('produksi_id')->nullable()->constrained('produksi')->onDelete('set null');
|
||||
$table->foreignId('profile_id')->nullable()->constrained('profiles')->onDelete('set null');
|
||||
$table->foreignId('lahan_id')->nullable()->constrained('map_lahan')->onDelete('set null');
|
||||
$table->foreignId('komoditas_id')->nullable()->constrained('master_komoditas')->onDelete('set null');
|
||||
$table->date('tanggal_pemeriksaan')->nullable();
|
||||
$table->string('grade')->nullable();
|
||||
$table->decimal('kadar_air', 8, 2)->nullable();
|
||||
$table->decimal('berat_bersih', 12, 2)->nullable();
|
||||
$table->decimal('berat_rusak', 12, 2)->nullable();
|
||||
$table->decimal('persentase_kerusakan', 8, 2)->nullable();
|
||||
$table->string('standar_mutu')->nullable();
|
||||
$table->string('status_kelayakan')->default('layak');
|
||||
$table->string('pemeriksa')->nullable();
|
||||
$table->text('catatan')->nullable();
|
||||
$table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null');
|
||||
$table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null');
|
||||
$table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('kualitas');
|
||||
}
|
||||
};
|
||||
@@ -1,6 +1,17 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
@php
|
||||
$desa = $profile?->desaKelurahan;
|
||||
$alamatLengkapParts = array_filter([
|
||||
$profile?->alamat,
|
||||
$desa?->nama,
|
||||
$desa?->kecamatan?->nama,
|
||||
$desa?->kecamatan?->kabupatenkota?->nama,
|
||||
$desa?->kecamatan?->kabupatenkota?->provinsi?->nama,
|
||||
]);
|
||||
$alamatLengkap = count($alamatLengkapParts) ? implode(', ', $alamatLengkapParts) : null;
|
||||
@endphp
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<!-- Header -->
|
||||
<div class="row">
|
||||
@@ -37,9 +48,6 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<a href="javascript:void(0)" class="btn btn-primary mb-1">
|
||||
<i class="icon-base ti tabler-user-check icon-xs me-2"></i>Connected
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -59,18 +67,8 @@
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="pages-profile-teams.html"
|
||||
><i class="icon-base ti tabler-lock icon-sm me-1_5"></i> Security</a
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="pages-profile-projects.html"
|
||||
><i class="icon-base ti tabler-layout-grid icon-sm me-1_5"></i> Projects</a
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="pages-profile-connections.html"
|
||||
><i class="icon-base ti tabler-link icon-sm me-1_5"></i> Connections</a
|
||||
<a class="nav-link" href="{{ route('userProfile.security') }}"
|
||||
><i class="icon-base ti tabler-lock icon-sm me-1_5"></i> Keamanan</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -85,28 +83,41 @@
|
||||
<!-- About User -->
|
||||
<div class="card mb-6">
|
||||
<div class="card-body">
|
||||
<p class="card-text text-uppercase text-body-secondary small mb-0">Tentang Pengguna</p>
|
||||
<div class="d-flex align-items-center justify-content-between gap-3">
|
||||
<p class="card-text text-uppercase text-body-secondary small mb-0">Tentang Pengguna</p>
|
||||
@if($profile)
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-icon btn-text-secondary rounded-pill"
|
||||
data-bs-toggle="offcanvas"
|
||||
data-bs-target="#editProfileOffcanvas"
|
||||
aria-controls="editProfileOffcanvas"
|
||||
title="Edit profil">
|
||||
<i class="icon-base ti tabler-edit icon-lg"></i>
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
<ul class="list-unstyled my-3 py-1">
|
||||
<li class="d-flex align-items-center mb-4">
|
||||
<li class="d-flex align-items-start mb-4">
|
||||
<i class="icon-base ti tabler-user icon-lg"></i
|
||||
><span class="fw-medium mx-2">Nama Lengkap:</span> <span>{{ $profile->nama ?? 'N/A' }}</span>
|
||||
</li>
|
||||
<li class="d-flex align-items-center mb-4">
|
||||
<li class="d-flex align-items-start mb-4">
|
||||
<i class="icon-base ti tabler-circles icon-lg"></i><span class="fw-medium mx-2">Role:</span>
|
||||
<span>{{ $profile->role ?? 'N/A' }}</span>
|
||||
</li>
|
||||
<li class="d-flex align-items-center mb-4">
|
||||
<i class="icon-base ti tabler-layout-collage icon-lg"></i><span class="fw-medium mx-2">Wilayah:</span>
|
||||
<span>{{ $profile->desa_kelurahan_id ?? 'N/A' }}</span>
|
||||
</li>
|
||||
<li class="d-flex align-items-center mb-4">
|
||||
<i class="icon-base ti tabler-layout-collage icon-lg"></i><span class="fw-medium mx-2">No KTP:</span>
|
||||
<li class="d-flex align-items-start mb-4">
|
||||
<i class="icon-base ti tabler-id icon-lg"></i><span class="fw-medium mx-2">No KTP:</span>
|
||||
<span>{{ $profile->ktp ?? 'N/A' }}</span>
|
||||
</li>
|
||||
<li class="d-flex align-items-center mb-4">
|
||||
<i class="icon-base ti tabler-layout-collage icon-lg"></i><span class="fw-medium mx-2">No KK:</span>
|
||||
<li class="d-flex align-items-start mb-4">
|
||||
<i class="icon-base ti tabler-users icon-lg"></i><span class="fw-medium mx-2">No KK:</span>
|
||||
<span>{{ $profile->kk ?? 'N/A' }}</span>
|
||||
</li>
|
||||
<li class="d-flex align-items-start mb-0">
|
||||
<i class="icon-base ti tabler-map-pin icon-lg flex-shrink-0"></i><span class="fw-medium mx-2">Alamat:</span>
|
||||
<span>{{ $alamatLengkap ?? 'N/A' }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="card-text text-uppercase text-body-secondary small mb-0">Kontak</p>
|
||||
<ul class="list-unstyled my-3 py-1">
|
||||
@@ -120,13 +131,21 @@
|
||||
<span>{{ $profile->email ?? 'N/A' }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="card-text text-uppercase text-body-secondary small mb-0">Teams</p>
|
||||
<p class="card-text text-uppercase text-body-secondary small mb-0">Akun</p>
|
||||
<ul class="list-unstyled mb-0 mt-3 pt-1">
|
||||
<li class="d-flex flex-wrap mb-4">
|
||||
<span class="fw-medium me-2">Backend Developer</span><span>(126 Members)</span>
|
||||
<li class="d-flex align-items-center mb-4">
|
||||
<i class="icon-base ti tabler-calendar icon-lg"></i>
|
||||
<span class="fw-medium mx-2">Tanggal Akun Dibuat:</span>
|
||||
<span>{{ auth()->user()->created_at?->format('F j, Y') ?? 'N/A' }}</span>
|
||||
</li>
|
||||
<li class="d-flex flex-wrap">
|
||||
<span class="fw-medium me-2">React Developer</span><span>(98 Members)</span>
|
||||
<li class="d-flex align-items-center">
|
||||
<i class="icon-base ti tabler-shield-check icon-lg"></i>
|
||||
<span class="fw-medium mx-2">Status Akun:</span>
|
||||
@if(auth()->user()->email_verified_at)
|
||||
<span class="badge bg-label-success">Aktif</span>
|
||||
@else
|
||||
<span class="badge bg-label-warning">Pending Verifikasi</span>
|
||||
@endif
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -135,19 +154,23 @@
|
||||
<!-- Profile Overview -->
|
||||
<div class="card mb-6">
|
||||
<div class="card-body">
|
||||
<p class="card-text text-uppercase text-body-secondary small">Overview</p>
|
||||
<p class="card-text text-uppercase text-body-secondary small">Overview Profil</p>
|
||||
<ul class="list-unstyled mb-0">
|
||||
<li class="d-flex align-items-center mb-4">
|
||||
<i class="icon-base ti tabler-plant icon-lg"></i
|
||||
><span class="fw-medium mx-2">Komoditas:</span> <span>13.5k</span>
|
||||
<i class="icon-base ti tabler-chart-treemap icon-lg"></i
|
||||
><span class="fw-medium mx-2">Lahan Saya:</span> <span>{{ number_format($jumlahLahan) }}</span>
|
||||
</li>
|
||||
<li class="d-flex align-items-center mb-4">
|
||||
<i class="icon-base ti tabler-chart-treemap icon-lg"></i
|
||||
><span class="fw-medium mx-2">Jumlah Lahan:</span> <span>146</span>
|
||||
<i class="icon-base ti tabler-map-plus icon-lg"></i
|
||||
><span class="fw-medium mx-2">Luas Lahan Saya:</span> <span>{{ number_format($totalLuasLahan, 2) }} Ha</span>
|
||||
</li>
|
||||
<li class="d-flex align-items-center mb-4">
|
||||
<i class="icon-base ti tabler-plant icon-lg"></i
|
||||
><span class="fw-medium mx-2">Tanaman Saya:</span> <span>{{ number_format($jumlahTanaman) }}</span>
|
||||
</li>
|
||||
<li class="d-flex align-items-center">
|
||||
<i class="icon-base ti tabler-map-plus icon-lg"></i
|
||||
><span class="fw-medium mx-2">Total Luas Lahan:</span> <span>897</span>
|
||||
<i class="icon-base ti tabler-plant icon-lg"></i
|
||||
><span class="fw-medium mx-2">Komoditas Saya:</span> <span>{{ number_format($jumlahKomoditas) }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -155,6 +178,34 @@
|
||||
<!--/ Profile Overview -->
|
||||
</div>
|
||||
<div class="col-xl-8 col-lg-7 col-md-7">
|
||||
@if(auth()->user()->role === \App\Enums\Role::SUPER_ADMIN)
|
||||
<div class="card mb-6">
|
||||
<div class="card-header align-items-center">
|
||||
<h5 class="card-action-title mb-0">
|
||||
<i class="icon-base ti tabler-alert-triangle icon-lg me-4"></i>Ringkasan Data Bermasalah
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul class="list-unstyled mb-0">
|
||||
@foreach($problemSummary as $problem)
|
||||
<li class="d-flex align-items-center justify-content-between gap-3 mb-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<i class="icon-base ti {{ $problem['icon'] }} icon-lg text-body-primary"></i>
|
||||
<span class="fw-medium mx-2">{{ $problem['label'] }}</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<span class="badge bg-label-secondary">{{ number_format($problem['count']) }}</span>
|
||||
<a href="{{ $problem['url'] }}" class="btn btn-sm btn-icon btn-text-secondary rounded-pill">
|
||||
<i class="icon-base ti tabler-arrow-right icon-md"></i>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Activity Timeline -->
|
||||
<div class="card card-action mb-6">
|
||||
<div class="card-header align-items-center">
|
||||
@@ -179,380 +230,229 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body pt-3">
|
||||
<ul class="timeline mb-0">
|
||||
<div class="card-body pt-3 activity-timeline-scroll">
|
||||
<ul class="timeline mb-0" id="activity-timeline" data-url="{{ route('userProfile.activities') }}">
|
||||
@forelse($activities as $activity)
|
||||
<li class="timeline-item timeline-item-transparent">
|
||||
<span class="timeline-point timeline-point-primary"></span>
|
||||
<span class="timeline-point timeline-point-{{ $activity['color'] }}"></span>
|
||||
<div class="timeline-event">
|
||||
<div class="timeline-header mb-3">
|
||||
<h6 class="mb-0">12 Invoices have been paid</h6>
|
||||
<small class="text-body-secondary">12 min ago</small>
|
||||
</div>
|
||||
<p class="mb-2">Invoices have been paid to the company</p>
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<div class="badge bg-lighter rounded d-flex align-items-center">
|
||||
<img src="../../assets//img/icons/misc/pdf.png" alt="img" width="15" class="me-2" />
|
||||
<span class="h6 mb-0 text-body">invoices.pdf</span>
|
||||
</div>
|
||||
<h6 class="mb-0">{{ $activity['title'] }}</h6>
|
||||
<small class="text-body-secondary">{{ $activity['time'] }}</small>
|
||||
</div>
|
||||
<p class="mb-2">{{ $activity['description'] }}</p>
|
||||
</div>
|
||||
</li>
|
||||
@empty
|
||||
<li class="timeline-item timeline-item-transparent">
|
||||
<span class="timeline-point timeline-point-success"></span>
|
||||
<span class="timeline-point timeline-point-secondary"></span>
|
||||
<div class="timeline-event">
|
||||
<div class="timeline-header mb-3">
|
||||
<h6 class="mb-0">Client Meeting</h6>
|
||||
<small class="text-body-secondary">45 min ago</small>
|
||||
</div>
|
||||
<p class="mb-2">Project meeting with john @10:15am</p>
|
||||
<div class="d-flex justify-content-between flex-wrap gap-2 mb-2">
|
||||
<div class="d-flex flex-wrap align-items-center mb-50">
|
||||
<div class="avatar avatar-sm me-2">
|
||||
<img src="../../assets/img/avatars/1.png" alt="Avatar" class="rounded-circle" />
|
||||
</div>
|
||||
<div>
|
||||
<p class="mb-0 small fw-medium">Lester McCarthy (Client)</p>
|
||||
<small>CEO of Pixinvent</small>
|
||||
</div>
|
||||
</div>
|
||||
<h6 class="mb-0">Belum ada aktivitas</h6>
|
||||
<small class="text-body-secondary">-</small>
|
||||
</div>
|
||||
<p class="mb-2">Aktivitas akan muncul setelah data dibuat, diubah, atau dihapus.</p>
|
||||
</div>
|
||||
</li>
|
||||
<li class="timeline-item timeline-item-transparent">
|
||||
<span class="timeline-point timeline-point-info"></span>
|
||||
<div class="timeline-event">
|
||||
<div class="timeline-header mb-3">
|
||||
<h6 class="mb-0">Create a new project for client</h6>
|
||||
<small class="text-body-secondary">2 Day Ago</small>
|
||||
</div>
|
||||
<p class="mb-2">6 team members in a project</p>
|
||||
<ul class="list-group list-group-flush">
|
||||
<li
|
||||
class="list-group-item d-flex justify-content-between align-items-center flex-wrap border-top-0 p-0">
|
||||
<div class="d-flex flex-wrap align-items-center">
|
||||
<ul class="list-unstyled users-list d-flex align-items-center avatar-group m-0 me-2">
|
||||
<li
|
||||
data-bs-toggle="tooltip"
|
||||
data-popup="tooltip-custom"
|
||||
data-bs-placement="top"
|
||||
title="Vinnie Mostowy"
|
||||
class="avatar pull-up">
|
||||
<img class="rounded-circle" src="../../assets/img/avatars/1.png" alt="Avatar" />
|
||||
</li>
|
||||
<li
|
||||
data-bs-toggle="tooltip"
|
||||
data-popup="tooltip-custom"
|
||||
data-bs-placement="top"
|
||||
title="Allen Rieske"
|
||||
class="avatar pull-up">
|
||||
<img class="rounded-circle" src="../../assets/img/avatars/4.png" alt="Avatar" />
|
||||
</li>
|
||||
<li
|
||||
data-bs-toggle="tooltip"
|
||||
data-popup="tooltip-custom"
|
||||
data-bs-placement="top"
|
||||
title="Julee Rossignol"
|
||||
class="avatar pull-up">
|
||||
<img class="rounded-circle" src="../../assets/img/avatars/2.png" alt="Avatar" />
|
||||
</li>
|
||||
<li class="avatar">
|
||||
<span
|
||||
class="avatar-initial rounded-circle pull-up"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="bottom"
|
||||
title="3 more"
|
||||
>+3</span
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
@endforelse
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Activity Timeline -->
|
||||
<div class="row">
|
||||
<!-- Connections -->
|
||||
<div class="col-lg-12 col-xl-6">
|
||||
<div class="card card-action mb-6">
|
||||
<div class="card-header align-items-center">
|
||||
<h5 class="card-action-title mb-0">Connections</h5>
|
||||
<div class="card-action-element">
|
||||
<div class="dropdown">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-icon btn-text-secondary rounded-pill dropdown-toggle hide-arrow p-0 text-body-secondary"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
<i class="icon-base ti tabler-dots-vertical icon-md text-body-secondary"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li><a class="dropdown-item" href="javascript:void(0);">Share connections</a></li>
|
||||
<li><a class="dropdown-item" href="javascript:void(0);">Suggest edits</a></li>
|
||||
<li>
|
||||
<hr class="dropdown-divider" />
|
||||
</li>
|
||||
<li><a class="dropdown-item" href="javascript:void(0);">Report bug</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul class="list-unstyled mb-0">
|
||||
<li class="mb-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar me-2">
|
||||
<img src="../../assets/img/avatars/2.png" alt="Avatar" class="rounded-circle" />
|
||||
</div>
|
||||
<div class="me-2">
|
||||
<h6 class="mb-0">Cecilia Payne</h6>
|
||||
<small>45 Connections</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
<button class="btn btn-label-primary btn-icon">
|
||||
<i class="icon-base ti tabler-user-check icon-22px"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="mb-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar me-2">
|
||||
<img src="../../assets/img/avatars/3.png" alt="Avatar" class="rounded-circle" />
|
||||
</div>
|
||||
<div class="me-2">
|
||||
<h6 class="mb-0">Curtis Fletcher</h6>
|
||||
<small>1.32k Connections</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
<button class="btn btn-primary btn-icon">
|
||||
<i class="icon-base ti tabler-user-x icon-22px"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="mb-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar me-2">
|
||||
<img src="../../assets/img/avatars/10.png" alt="Avatar" class="rounded-circle" />
|
||||
</div>
|
||||
<div class="me-2">
|
||||
<h6 class="mb-0">Alice Stone</h6>
|
||||
<small>125 Connections</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
<button class="btn btn-primary btn-icon">
|
||||
<i class="icon-base ti tabler-user-x icon-22px"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="mb-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar me-2">
|
||||
<img src="../../assets/img/avatars/7.png" alt="Avatar" class="rounded-circle" />
|
||||
</div>
|
||||
<div class="me-2">
|
||||
<h6 class="mb-0">Darrell Barnes</h6>
|
||||
<small>456 Connections</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
<button class="btn btn-label-primary btn-icon">
|
||||
<i class="icon-base ti tabler-user-check icon-22px"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="mb-6">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar me-2">
|
||||
<img src="../../assets/img/avatars/12.png" alt="Avatar" class="rounded-circle" />
|
||||
</div>
|
||||
<div class="me-2">
|
||||
<h6 class="mb-0">Eugenia Moore</h6>
|
||||
<small>1.2k Connections</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
<button class="btn btn-label-primary btn-icon">
|
||||
<i class="icon-base ti tabler-user-check icon-22px"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="text-center">
|
||||
<a href="javascript:;">View all connections</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Connections -->
|
||||
<!-- Teams -->
|
||||
<div class="col-lg-12 col-xl-6">
|
||||
<div class="card card-action mb-6">
|
||||
<div class="card-header align-items-center">
|
||||
<h5 class="card-action-title mb-0">Teams</h5>
|
||||
<div class="card-action-element">
|
||||
<div class="dropdown">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-icon btn-text-secondary dropdown-toggle hide-arrow p-0"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
<i class="icon-base ti tabler-dots-vertical icon-md text-body-secondary"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li><a class="dropdown-item" href="javascript:void(0);">Share teams</a></li>
|
||||
<li><a class="dropdown-item" href="javascript:void(0);">Suggest edits</a></li>
|
||||
<li>
|
||||
<hr class="dropdown-divider" />
|
||||
</li>
|
||||
<li><a class="dropdown-item" href="javascript:void(0);">Report bug</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul class="list-unstyled mb-0">
|
||||
<li class="mb-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar me-2">
|
||||
<img
|
||||
src="../../assets/img/icons/brands/react-label.png"
|
||||
alt="Avatar"
|
||||
class="rounded-circle" />
|
||||
</div>
|
||||
<div class="me-2">
|
||||
<h6 class="mb-0">React Developers</h6>
|
||||
<small>72 Members</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
<a href="javascript:;"><span class="badge bg-label-danger">Developer</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="mb-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar me-2">
|
||||
<img
|
||||
src="../../assets/img/icons/brands/support-label.png"
|
||||
alt="Avatar"
|
||||
class="rounded-circle" />
|
||||
</div>
|
||||
<div class="me-2">
|
||||
<h6 class="mb-0">Support Team</h6>
|
||||
<small>122 Members</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
<a href="javascript:;"><span class="badge bg-label-primary">Support</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="mb-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar me-2">
|
||||
<img
|
||||
src="../../assets/img/icons/brands/figma-label.png"
|
||||
alt="Avatar"
|
||||
class="rounded-circle" />
|
||||
</div>
|
||||
<div class="me-2">
|
||||
<h6 class="mb-0">UI Designers</h6>
|
||||
<small>7 Members</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
<a href="javascript:;"><span class="badge bg-label-info">Designer</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="mb-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar me-2">
|
||||
<img
|
||||
src="../../assets/img/icons/brands/vue-label.png"
|
||||
alt="Avatar"
|
||||
class="rounded-circle" />
|
||||
</div>
|
||||
<div class="me-2">
|
||||
<h6 class="mb-0">Vue.js Developers</h6>
|
||||
<small>289 Members</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
<a href="javascript:;"><span class="badge bg-label-danger">Developer</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="mb-6">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar me-2">
|
||||
<img
|
||||
src="../../assets/img/icons/brands/twitter-label.png"
|
||||
alt="Avatar"
|
||||
class="rounded-circle" />
|
||||
</div>
|
||||
<div class="me-w">
|
||||
<h6 class="mb-0">Digital Marketing</h6>
|
||||
<small>24 Members</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
<a href="javascript:;"><span class="badge bg-label-secondary">Marketing</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="text-center">
|
||||
<a href="javascript:;">View all teams</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Teams -->
|
||||
</div>
|
||||
<!-- Projects table -->
|
||||
<!-- <div class="card mb-6">
|
||||
<div class="mb-4">
|
||||
<table class="table datatable-project">
|
||||
<thead class="border-top">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th>Project</th>
|
||||
<th>Leader</th>
|
||||
<th>Team</th>
|
||||
<th class="w-px-200">Progress</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
</div> -->
|
||||
<!--/ Projects table -->
|
||||
</div>
|
||||
</div>
|
||||
<!--/ User Profile Content -->
|
||||
|
||||
@if($profile)
|
||||
<div
|
||||
class="offcanvas offcanvas-end"
|
||||
tabindex="-1"
|
||||
id="editProfileOffcanvas"
|
||||
aria-labelledby="editProfileOffcanvasLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 id="editProfileOffcanvasLabel" class="offcanvas-title">Edit Profil</h5>
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<form id="profileQuickEditForm" action="{{ route('profile.update', $profile->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<input type="hidden" name="desa_kelurahan_id" value="{{ $profile->desa_kelurahan_id }}">
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="quick-profile-nama">Nama Lengkap</label>
|
||||
<input type="text" class="form-control" id="quick-profile-nama" name="nama" value="{{ $profile->nama }}" required>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="quick-profile-role">Role</label>
|
||||
<input type="text" class="form-control" id="quick-profile-role" value="{{ $profile->role ?? '-' }}" disabled>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="quick-profile-email">Email</label>
|
||||
<input type="email" class="form-control" id="quick-profile-email" name="email" value="{{ $profile->email }}" required>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="quick-profile-telepon">Telepon</label>
|
||||
<input type="text" class="form-control" id="quick-profile-telepon" name="telepon" value="{{ $profile->telepon }}" maxlength="13" required>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="quick-profile-ktp">No KTP</label>
|
||||
<input type="text" class="form-control" id="quick-profile-ktp" name="ktp" value="{{ $profile->ktp }}" maxlength="16">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="quick-profile-kk">No KK</label>
|
||||
<input type="text" class="form-control" id="quick-profile-kk" name="kk" value="{{ $profile->kk }}" maxlength="16">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="quick-profile-alamat">Alamat</label>
|
||||
<textarea class="form-control" id="quick-profile-alamat" name="alamat" rows="4">{{ $profile->alamat }}</textarea>
|
||||
<div class="form-text">Wilayah desa sampai provinsi tetap mengikuti data wilayah profil.</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end gap-2">
|
||||
<button type="button" class="btn btn-label-secondary" data-bs-dismiss="offcanvas">Batal</button>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="icon-base ti tabler-device-floppy icon-xs me-2"></i>Simpan
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endsection
|
||||
@endsection
|
||||
|
||||
@push('scripts-head')
|
||||
<style>
|
||||
.activity-timeline-scroll {
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const timeline = document.getElementById('activity-timeline');
|
||||
const profileQuickEditForm = document.getElementById('profileQuickEditForm');
|
||||
|
||||
if (profileQuickEditForm) {
|
||||
profileQuickEditForm.addEventListener('submit', function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
fetch(profileQuickEditForm.action, {
|
||||
method: 'POST',
|
||||
body: new FormData(profileQuickEditForm),
|
||||
headers: {
|
||||
Accept: 'application/json'
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
return response.json().then(function (data) {
|
||||
return { ok: response.ok, data: data };
|
||||
});
|
||||
})
|
||||
.then(function (result) {
|
||||
if (!result.ok) {
|
||||
const errors = result.data.errors ? Object.values(result.data.errors).flat().join('<br>') : result.data.message;
|
||||
if (window.Swal) {
|
||||
Swal.fire({ icon: 'error', title: 'Gagal!', html: errors || 'Data belum berhasil disimpan.' });
|
||||
} else {
|
||||
alert(errors || 'Data belum berhasil disimpan.');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.Swal) {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Berhasil!',
|
||||
text: result.data.message || 'Profil berhasil diperbarui.',
|
||||
timer: 1500,
|
||||
showConfirmButton: false
|
||||
}).then(function () {
|
||||
window.location.reload();
|
||||
});
|
||||
} else {
|
||||
window.location.reload();
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
if (window.Swal) {
|
||||
Swal.fire({ icon: 'error', title: 'Gagal!', text: 'Koneksi bermasalah atau terjadi kesalahan server.' });
|
||||
} else {
|
||||
alert('Koneksi bermasalah atau terjadi kesalahan server.');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (!timeline) {
|
||||
return;
|
||||
}
|
||||
|
||||
const escapeHtml = function (value) {
|
||||
return String(value ?? '')
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
};
|
||||
|
||||
const renderActivities = function (activities) {
|
||||
if (!activities.length) {
|
||||
timeline.innerHTML = `
|
||||
<li class="timeline-item timeline-item-transparent">
|
||||
<span class="timeline-point timeline-point-secondary"></span>
|
||||
<div class="timeline-event">
|
||||
<div class="timeline-header mb-3">
|
||||
<h6 class="mb-0">Belum ada aktivitas</h6>
|
||||
<small class="text-body-secondary">-</small>
|
||||
</div>
|
||||
<p class="mb-2">Aktivitas akan muncul setelah data dibuat, diubah, atau dihapus.</p>
|
||||
</div>
|
||||
</li>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
timeline.innerHTML = activities.map(function (activity) {
|
||||
return `
|
||||
<li class="timeline-item timeline-item-transparent">
|
||||
<span class="timeline-point timeline-point-${escapeHtml(activity.color)}"></span>
|
||||
<div class="timeline-event">
|
||||
<div class="timeline-header mb-3">
|
||||
<h6 class="mb-0">${escapeHtml(activity.title)}</h6>
|
||||
<small class="text-body-secondary">${escapeHtml(activity.time)}</small>
|
||||
</div>
|
||||
<p class="mb-2">${escapeHtml(activity.description)}</p>
|
||||
</div>
|
||||
</li>
|
||||
`;
|
||||
}).join('');
|
||||
};
|
||||
|
||||
const loadActivities = function () {
|
||||
fetch(timeline.dataset.url, {
|
||||
headers: {
|
||||
Accept: 'application/json'
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
return response.ok ? response.json() : null;
|
||||
})
|
||||
.then(function (data) {
|
||||
if (data && Array.isArray(data.activities)) {
|
||||
renderActivities(data.activities);
|
||||
}
|
||||
})
|
||||
.catch(function () {});
|
||||
};
|
||||
|
||||
setInterval(loadActivities, 15000);
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card mb-6">
|
||||
<div class="user-profile-header d-flex flex-column flex-lg-row text-sm-start text-center mb-5">
|
||||
<div class="flex-grow-1 mt-3 mt-lg-5">
|
||||
<div class="d-flex align-items-md-end align-items-sm-start align-items-center justify-content-md-between justify-content-start mx-5 flex-md-row flex-column gap-4">
|
||||
<div class="user-profile-info">
|
||||
<h4 class="mb-2 mt-lg-6">{{ $profile->nama ?? 'Guest' }}</h4>
|
||||
<ul class="list-inline mb-0 d-flex align-items-center flex-wrap justify-content-sm-start justify-content-center gap-4 my-2">
|
||||
<li class="list-inline-item d-flex gap-2 align-items-center">
|
||||
<i class="icon-base ti tabler-circles icon-lg"></i>
|
||||
<span class="fw-medium">{{ $profile->role ?? 'N/A' }}</span>
|
||||
</li>
|
||||
<li class="list-inline-item d-flex gap-2 align-items-center">
|
||||
<i class="icon-base ti tabler-map-pin icon-lg"></i>
|
||||
<span class="fw-medium">{{ $profile->alamat ?? 'N/A' }}</span>
|
||||
</li>
|
||||
<li class="list-inline-item d-flex gap-2 align-items-center">
|
||||
<i class="icon-base ti tabler-calendar icon-lg"></i>
|
||||
<span class="fw-medium">{{ $profile?->created_at?->format('F j, Y') ?? 'N/A' }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<a href="javascript:void(0)" class="btn btn-primary mb-1">
|
||||
<i class="icon-base ti tabler-shield-lock icon-xs me-2"></i>Keamanan
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="nav-align-top">
|
||||
<ul class="nav nav-pills flex-column flex-sm-row mb-6 gap-sm-0 gap-2">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('userProfile.index') }}">
|
||||
<i class="icon-base ti tabler-user-check icon-sm me-1_5"></i> Profile
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="{{ route('userProfile.security') }}">
|
||||
<i class="icon-base ti tabler-lock icon-sm me-1_5"></i> Keamanan
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-6">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="icon-base ti tabler-shield-lock icon-lg me-2"></i>Keamanan Akun
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@if(session('security_success'))
|
||||
<div class="alert alert-success mb-4">{{ session('security_success') }}</div>
|
||||
@endif
|
||||
|
||||
<div class="row g-6">
|
||||
<div class="col-lg-6">
|
||||
<p class="card-text text-uppercase text-body-secondary small mb-3">Ubah Password</p>
|
||||
<form action="{{ route('userProfile.password.update') }}" method="POST">
|
||||
@csrf
|
||||
@method('PATCH')
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="current_password">Password Saat Ini</label>
|
||||
<input type="password" class="form-control @error('current_password') is-invalid @enderror" id="current_password" name="current_password" autocomplete="current-password" />
|
||||
@error('current_password')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="password">Password Baru</label>
|
||||
<input type="password" class="form-control @error('password') is-invalid @enderror" id="password" name="password" autocomplete="new-password" />
|
||||
@error('password')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="password_confirmation">Konfirmasi Password Baru</label>
|
||||
<input type="password" class="form-control" id="password_confirmation" name="password_confirmation" autocomplete="new-password" />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="icon-base ti tabler-key icon-xs me-2"></i>Ubah Password
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6">
|
||||
<p class="card-text text-uppercase text-body-secondary small mb-3">Status Verifikasi</p>
|
||||
<ul class="list-unstyled mb-5">
|
||||
<li class="d-flex align-items-center mb-3">
|
||||
<i class="icon-base ti tabler-mail-check icon-lg"></i>
|
||||
<span class="fw-medium mx-2">Email:</span>
|
||||
<span>{{ auth()->user()->email }}</span>
|
||||
</li>
|
||||
<li class="d-flex align-items-center">
|
||||
<i class="icon-base ti tabler-shield-check icon-lg"></i>
|
||||
<span class="fw-medium mx-2">Status:</span>
|
||||
@if(auth()->user()->email_verified_at)
|
||||
<span class="badge bg-label-success">Terverifikasi</span>
|
||||
@else
|
||||
<span class="badge bg-label-warning">Belum Terverifikasi</span>
|
||||
@endif
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="d-flex align-items-center justify-content-between gap-3 mb-3">
|
||||
<p class="card-text text-uppercase text-body-secondary small mb-0">Riwayat Login</p>
|
||||
<form action="{{ route('userProfile.logoutDevices') }}" method="POST">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-sm btn-label-danger">
|
||||
<i class="icon-base ti tabler-logout icon-xs me-1"></i>Logout Semua Perangkat
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<ul class="list-unstyled mb-0">
|
||||
@forelse($loginSessions as $loginSession)
|
||||
<li class="d-flex align-items-start mb-4">
|
||||
<i class="icon-base ti tabler-device-desktop icon-lg mt-1"></i>
|
||||
<div class="ms-2">
|
||||
<div class="fw-medium">
|
||||
{{ $loginSession->ip_address ?? 'IP tidak tersedia' }}
|
||||
@if($loginSession->is_current)
|
||||
<span class="badge bg-label-primary ms-1">Saat Ini</span>
|
||||
@endif
|
||||
</div>
|
||||
<small class="text-body-secondary d-block">{{ $loginSession->last_activity->diffForHumans() }}</small>
|
||||
<small class="text-body-secondary d-block text-truncate" style="max-width: 360px;">{{ $loginSession->user_agent ?? 'Perangkat tidak tersedia' }}</small>
|
||||
</div>
|
||||
</li>
|
||||
@empty
|
||||
<li class="text-body-secondary">Riwayat login belum tersedia.</li>
|
||||
@endforelse
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -68,34 +68,41 @@
|
||||
<li class="menu-header small">
|
||||
<span class="menu-header-text" data-i18n="Ekosistem">Ekosistem</span>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<li class="menu-item {{ request()->routeIs(['profile.*', 'produksi.*', 'kualitas.*', 'lahan.*', 'tanaman.*']) ? 'active open' : '' }}">
|
||||
<a href="javascript:void(0);" class="menu-link menu-toggle">
|
||||
<i class="menu-icon icon-base ti tabler-file-description"></i>
|
||||
<div data-i18n="Data Pertanian">Data Pertanian</div>
|
||||
</a>
|
||||
<ul class="menu-sub">
|
||||
<li class="menu-item">
|
||||
<li class="menu-item {{ request()->routeIs('profile.*') ? 'active' : '' }}">
|
||||
<a href="{{ route('profile.index') }}" class="menu-link">
|
||||
<div data-i18n="Profil Petani">Profil Petani</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="menu-sub">
|
||||
<li class="menu-item">
|
||||
<a href="#" class="menu-link">
|
||||
<div data-i18n="Produksi & Kualitas">Produksi & Kualitas</div>
|
||||
<li class="menu-item {{ request()->routeIs('produksi.*') ? 'active' : '' }}">
|
||||
<a href="{{ route('produksi.index') }}" class="menu-link">
|
||||
<div data-i18n="Produksi">Produksi</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="menu-sub">
|
||||
<li class="menu-item">
|
||||
<li class="menu-item {{ request()->routeIs('kualitas.*') ? 'active' : '' }}">
|
||||
<a href="{{ route('kualitas.index') }}" class="menu-link">
|
||||
<div data-i18n="Kualitas">Kualitas</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="menu-sub">
|
||||
<li class="menu-item {{ request()->routeIs('lahan.*') ? 'active' : '' }}">
|
||||
<a href="{{ route('lahan.index') }}" class="menu-link">
|
||||
<div data-i18n="Pemantauan Lahan">Pemantauan Lahan</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="menu-sub">
|
||||
<li class="menu-item">
|
||||
<li class="menu-item {{ request()->routeIs('tanaman.*') ? 'active' : '' }}">
|
||||
<a href="{{ route('tanaman.index') }}" class="menu-link">
|
||||
<div data-i18n="Pemantauan Tanaman">Pemantauan Tanaman</div>
|
||||
</a>
|
||||
@@ -294,4 +301,4 @@
|
||||
<i class="ti tabler-menu icon-base"></i>
|
||||
<i class="ti tabler-chevron-right icon-base"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
@csrf
|
||||
|
||||
@if(isset($kualitas))
|
||||
@method('PUT')
|
||||
@endif
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Referensi Produksi</label>
|
||||
<select name="produksi_id" class="form-select @error('produksi_id') is-invalid @enderror">
|
||||
<option value="">Pilih Produksi</option>
|
||||
@foreach($produksi as $item)
|
||||
<option value="{{ $item->id }}" {{ old('produksi_id', $kualitas->produksi_id ?? '') == $item->id ? 'selected' : '' }}>
|
||||
{{ $item->kode_produksi ?? 'Produksi #' . $item->id }} - {{ $item->komoditas->nama ?? '-' }} - {{ $item->profile->nama ?? '-' }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('produksi_id')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Tanggal Pemeriksaan</label>
|
||||
<input type="date" name="tanggal_pemeriksaan" class="form-control @error('tanggal_pemeriksaan') is-invalid @enderror" value="{{ old('tanggal_pemeriksaan', isset($kualitas) && $kualitas->tanggal_pemeriksaan ? $kualitas->tanggal_pemeriksaan->format('Y-m-d') : '') }}">
|
||||
@error('tanggal_pemeriksaan')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<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>
|
||||
<option value="">Pilih Petani</option>
|
||||
@foreach($profiles as $profile)
|
||||
<option value="{{ $profile->id }}" {{ old('profile_id', $kualitas->profile_id ?? '') == $profile->id ? 'selected' : '' }}>{{ $profile->nama }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('profile_id')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<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>
|
||||
<option value="">Pilih Petani terlebih dahulu</option>
|
||||
</select>
|
||||
@error('lahan_id')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Komoditas <span class="text-danger">*</span></label>
|
||||
<select name="komoditas_id" class="form-select @error('komoditas_id') is-invalid @enderror" required>
|
||||
<option value="">Pilih Komoditas</option>
|
||||
@foreach($komoditas as $item)
|
||||
<option value="{{ $item->id }}" {{ old('komoditas_id', $kualitas->komoditas_id ?? '') == $item->id ? 'selected' : '' }}>{{ $item->nama }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('komoditas_id')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Grade <span class="text-danger">*</span></label>
|
||||
<select name="grade" class="form-select @error('grade') is-invalid @enderror" required>
|
||||
<option value="">Pilih Grade</option>
|
||||
@foreach(['A', 'B', 'C', 'Reject'] as $grade)
|
||||
<option value="{{ $grade }}" {{ old('grade', $kualitas->grade ?? '') == $grade ? 'selected' : '' }}>{{ $grade }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('grade')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Kadar Air (%)</label>
|
||||
<input type="number" step="0.01" name="kadar_air" class="form-control @error('kadar_air') is-invalid @enderror" value="{{ old('kadar_air', $kualitas->kadar_air ?? '') }}">
|
||||
@error('kadar_air')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Status Kelayakan <span class="text-danger">*</span></label>
|
||||
<select name="status_kelayakan" class="form-select @error('status_kelayakan') is-invalid @enderror" required>
|
||||
@foreach(['layak' => 'Layak', 'perlu_sortir' => 'Perlu Sortir', 'tidak_layak' => 'Tidak Layak'] as $value => $label)
|
||||
<option value="{{ $value }}" {{ old('status_kelayakan', $kualitas->status_kelayakan ?? 'layak') == $value ? 'selected' : '' }}>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('status_kelayakan')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Berat Bersih</label>
|
||||
<input type="number" step="0.01" name="berat_bersih" class="form-control @error('berat_bersih') is-invalid @enderror" value="{{ old('berat_bersih', $kualitas->berat_bersih ?? '') }}">
|
||||
@error('berat_bersih')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Berat Rusak</label>
|
||||
<input type="number" step="0.01" name="berat_rusak" class="form-control @error('berat_rusak') is-invalid @enderror" value="{{ old('berat_rusak', $kualitas->berat_rusak ?? '') }}">
|
||||
@error('berat_rusak')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Standar Mutu</label>
|
||||
<input type="text" name="standar_mutu" class="form-control @error('standar_mutu') is-invalid @enderror" value="{{ old('standar_mutu', $kualitas->standar_mutu ?? '') }}" placeholder="Contoh: SNI / Internal">
|
||||
@error('standar_mutu')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Pemeriksa</label>
|
||||
<input type="text" name="pemeriksa" class="form-control @error('pemeriksa') is-invalid @enderror" value="{{ old('pemeriksa', $kualitas->pemeriksa ?? '') }}">
|
||||
@error('pemeriksa')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Catatan</label>
|
||||
<textarea name="catatan" class="form-control @error('catatan') is-invalid @enderror" rows="3">{{ old('catatan', $kualitas->catatan ?? '') }}</textarea>
|
||||
@error('catatan')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-end">
|
||||
<a href="{{ route('kualitas.index') }}" class="btn btn-label-secondary me-2">Batal</a>
|
||||
<button type="submit" class="btn btn-primary"><i class="ti tabler-device-floppy me-1"></i> Simpan</button>
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
@php
|
||||
$lahanOptions = $lahan->map(function ($item) {
|
||||
return [
|
||||
'id' => $item->id,
|
||||
'profile_id' => $item->profile_id,
|
||||
'nama' => $item->nama,
|
||||
];
|
||||
})->values();
|
||||
@endphp
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const profileSelect = document.getElementById('profile_id');
|
||||
const lahanSelect = document.getElementById('lahan_id');
|
||||
const selectedLahanId = "{{ old('lahan_id', $kualitas->lahan_id ?? '') }}";
|
||||
const lahanOptions = @json($lahanOptions);
|
||||
|
||||
function renderLahanOptions() {
|
||||
const profileId = profileSelect.value;
|
||||
|
||||
lahanSelect.innerHTML = '';
|
||||
|
||||
if (!profileId) {
|
||||
lahanSelect.disabled = true;
|
||||
lahanSelect.add(new Option('Pilih Petani terlebih dahulu', ''));
|
||||
return;
|
||||
}
|
||||
|
||||
const filteredLahan = lahanOptions.filter((item) => String(item.profile_id) === String(profileId));
|
||||
|
||||
lahanSelect.disabled = false;
|
||||
lahanSelect.add(new Option(filteredLahan.length ? 'Pilih Lahan' : 'Petani ini belum memiliki lahan', ''));
|
||||
|
||||
filteredLahan.forEach((item) => {
|
||||
const option = new Option(item.nama, item.id);
|
||||
option.selected = String(item.id) === String(selectedLahanId);
|
||||
lahanSelect.add(option);
|
||||
});
|
||||
|
||||
if (!filteredLahan.length) {
|
||||
lahanSelect.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
profileSelect.addEventListener('change', function () {
|
||||
renderLahanOptions();
|
||||
lahanSelect.value = '';
|
||||
});
|
||||
|
||||
renderLahanOptions();
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@@ -0,0 +1,17 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="card">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0">Tambah Data Kualitas</h5>
|
||||
<a href="{{ route('kualitas.index') }}" class="btn btn-sm btn-label-secondary"><i class="ti tabler-arrow-left me-1"></i> Kembali</a>
|
||||
</div>
|
||||
<div class="card-body pt-4">
|
||||
<form action="{{ route('kualitas.store') }}" method="POST">
|
||||
@include('produktivitas.kualitas._form')
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,17 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="card">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0">Edit Data Kualitas</h5>
|
||||
<a href="{{ route('kualitas.index') }}" class="btn btn-sm btn-label-secondary"><i class="ti tabler-arrow-left me-1"></i> Kembali</a>
|
||||
</div>
|
||||
<div class="card-body pt-4">
|
||||
<form action="{{ route('kualitas.update', $kualitas->id) }}" method="POST">
|
||||
@include('produktivitas.kualitas._form')
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,128 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
@if(session('success'))
|
||||
<div class="alert alert-success alert-dismissible" role="alert">
|
||||
{{ session('success') }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0">Data Kualitas</h5>
|
||||
<a href="{{ route('kualitas.create') }}" class="btn btn-sm btn-primary"><i class="ti tabler-plus me-1"></i> Tambah Kualitas</a>
|
||||
</div>
|
||||
<div class="card-body border-bottom pt-4">
|
||||
<form method="GET" action="{{ route('kualitas.index') }}" class="d-flex justify-content-between align-items-center row gap-3 gap-md-0">
|
||||
<div class="col-md-auto d-flex align-items-center">
|
||||
<label class="me-2 text-nowrap">Show</label>
|
||||
<select name="per_page" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
|
||||
@foreach([10, 25, 50] as $size)
|
||||
<option value="{{ $size }}" {{ request('per_page', 10) == $size ? 'selected' : '' }}>{{ $size }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<label class="ms-2 text-nowrap">entries</label>
|
||||
</div>
|
||||
<div class="col-md-auto d-flex gap-2">
|
||||
<select name="status_kelayakan" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
|
||||
<option value="">Semua Status</option>
|
||||
<option value="layak" {{ request('status_kelayakan') == 'layak' ? 'selected' : '' }}>Layak</option>
|
||||
<option value="perlu_sortir" {{ request('status_kelayakan') == 'perlu_sortir' ? 'selected' : '' }}>Perlu Sortir</option>
|
||||
<option value="tidak_layak" {{ request('status_kelayakan') == 'tidak_layak' ? 'selected' : '' }}>Tidak Layak</option>
|
||||
</select>
|
||||
<div class="input-group input-group-sm w-auto">
|
||||
<input type="text" name="search" class="form-control" placeholder="Cari kualitas..." value="{{ request('search') }}">
|
||||
<button type="submit" class="btn btn-outline-primary"><i class="ti tabler-search"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive text-nowrap">
|
||||
<table class="table table-hover">
|
||||
<thead class="border-top">
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Produksi</th>
|
||||
<th>Petani</th>
|
||||
<th>Komoditas</th>
|
||||
<th>Grade</th>
|
||||
<th>Kadar Air</th>
|
||||
<th>Kerusakan</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($kualitas as $index => $item)
|
||||
<tr>
|
||||
<td>{{ $kualitas->firstItem() + $index }}</td>
|
||||
<td>{{ $item->produksi->kode_produksi ?? '-' }}</td>
|
||||
<td>{{ $item->profile->nama ?? '-' }}</td>
|
||||
<td>{{ $item->komoditas->nama ?? '-' }}</td>
|
||||
<td><span class="badge bg-label-primary">{{ $item->grade ?? '-' }}</span></td>
|
||||
<td>{{ $item->kadar_air ? $item->kadar_air . '%' : '-' }}</td>
|
||||
<td>{{ $item->persentase_kerusakan ? $item->persentase_kerusakan . '%' : '-' }}</td>
|
||||
<td>
|
||||
@php($statusClass = ['layak' => 'success', 'perlu_sortir' => 'warning', 'tidak_layak' => 'danger'][$item->status_kelayakan] ?? 'secondary')
|
||||
<span class="badge bg-label-{{ $statusClass }}">{{ ucwords(str_replace('_', ' ', $item->status_kelayakan)) }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<a href="{{ route('kualitas.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 ?? 'Kualitas' }}"><i class="ti tabler-trash ti-md"></i></a>
|
||||
<a href="{{ route('kualitas.show', $item->id) }}" class="btn btn-icon btn-text-secondary rounded-pill"><i class="ti tabler-eye ti-md"></i></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="9" class="text-center py-4">Tidak ada data kualitas ditemukan.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-footer d-flex justify-content-center justify-content-md-end border-top">
|
||||
{{ $kualitas->appends(request()->query())->links('pagination::bootstrap-5') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
const csrfTokenKualitas = "{{ csrf_token() }}";
|
||||
|
||||
$(document).on('click', '.delete-record', function () {
|
||||
const id = $(this).data('id');
|
||||
const name = $(this).data('nama');
|
||||
|
||||
Swal.fire({
|
||||
title: 'Hapus Kualitas?',
|
||||
text: `Data "${name}" akan dihapus.`,
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Ya, Hapus!',
|
||||
cancelButtonText: 'Batal',
|
||||
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
|
||||
buttonsStyling: false
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
$.ajax({
|
||||
url: `/kualitas/${id}`,
|
||||
type: 'DELETE',
|
||||
headers: { 'X-CSRF-TOKEN': csrfTokenKualitas },
|
||||
success: function (res) {
|
||||
Swal.fire({ icon: 'success', title: 'Terhapus!', text: res.message, showConfirmButton: false, timer: 1500 })
|
||||
.then(() => window.location.reload());
|
||||
},
|
||||
error: function () {
|
||||
Swal.fire({ icon: 'error', title: 'Gagal!', text: 'Terjadi kesalahan saat menghapus data.' });
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@@ -0,0 +1,40 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="card">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0">Detail Kualitas</h5>
|
||||
<a href="{{ route('kualitas.index') }}" class="btn btn-sm btn-label-secondary"><i class="ti tabler-arrow-left me-1"></i> Kembali</a>
|
||||
</div>
|
||||
<div class="card-body pt-4">
|
||||
<div class="row g-3">
|
||||
@foreach([
|
||||
'Produksi' => $kualitas->produksi->kode_produksi ?? '-',
|
||||
'Tanggal Pemeriksaan' => $kualitas->tanggal_pemeriksaan ? $kualitas->tanggal_pemeriksaan->format('d-m-Y') : '-',
|
||||
'Petani' => $kualitas->profile->nama ?? '-',
|
||||
'Lahan' => $kualitas->lahan->nama ?? '-',
|
||||
'Komoditas' => $kualitas->komoditas->nama ?? '-',
|
||||
'Grade' => $kualitas->grade,
|
||||
'Kadar Air' => $kualitas->kadar_air ? $kualitas->kadar_air . '%' : '-',
|
||||
'Berat Bersih' => $kualitas->berat_bersih,
|
||||
'Berat Rusak' => $kualitas->berat_rusak,
|
||||
'Persentase Kerusakan' => $kualitas->persentase_kerusakan ? $kualitas->persentase_kerusakan . '%' : '-',
|
||||
'Standar Mutu' => $kualitas->standar_mutu,
|
||||
'Status Kelayakan' => ucwords(str_replace('_', ' ', $kualitas->status_kelayakan)),
|
||||
'Pemeriksa' => $kualitas->pemeriksa,
|
||||
] as $label => $value)
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-muted">{{ $label }}</label>
|
||||
<div class="fw-medium">{{ $value ?? '-' }}</div>
|
||||
</div>
|
||||
@endforeach
|
||||
<div class="col-12">
|
||||
<label class="form-label text-muted">Catatan</label>
|
||||
<div>{{ $kualitas->catatan ?? '-' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,157 @@
|
||||
@csrf
|
||||
|
||||
@if(isset($produksi))
|
||||
@method('PUT')
|
||||
@endif
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Kode Produksi</label>
|
||||
<input type="text" name="kode_produksi" class="form-control @error('kode_produksi') is-invalid @enderror" value="{{ old('kode_produksi', $produksi->kode_produksi ?? '') }}" placeholder="Contoh: PRD-2026-001">
|
||||
@error('kode_produksi')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Periode</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 class="col-md-6 mb-3">
|
||||
<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>
|
||||
<option value="">Pilih Petani</option>
|
||||
@foreach($profiles as $profile)
|
||||
<option value="{{ $profile->id }}" {{ old('profile_id', $produksi->profile_id ?? '') == $profile->id ? 'selected' : '' }}>{{ $profile->nama }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('profile_id')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<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>
|
||||
<option value="">Pilih Petani terlebih dahulu</option>
|
||||
</select>
|
||||
@error('lahan_id')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Tanaman</label>
|
||||
<select name="tanaman_id" class="form-select @error('tanaman_id') is-invalid @enderror">
|
||||
<option value="">Pilih Tanaman</option>
|
||||
@foreach($tanaman as $item)
|
||||
<option value="{{ $item->id }}" {{ old('tanaman_id', $produksi->tanaman_id ?? '') == $item->id ? 'selected' : '' }}>{{ $item->nama }}{{ $item->komoditas ? ' - ' . $item->komoditas->nama : '' }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('tanaman_id')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Komoditas <span class="text-danger">*</span></label>
|
||||
<select name="komoditas_id" class="form-select @error('komoditas_id') is-invalid @enderror" required>
|
||||
<option value="">Pilih Komoditas</option>
|
||||
@foreach($komoditas as $item)
|
||||
<option value="{{ $item->id }}" {{ old('komoditas_id', $produksi->komoditas_id ?? '') == $item->id ? 'selected' : '' }}>{{ $item->nama }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('komoditas_id')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Tanggal Panen</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') : '') }}">
|
||||
@error('tanggal_panen')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Luas Tanam</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 ?? '') }}">
|
||||
@error('luas_tanam')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Luas 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 ?? '') }}">
|
||||
@error('luas_panen')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Jumlah Panen</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 ?? '') }}">
|
||||
@error('jumlah_panen')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label">Satuan <span class="text-danger">*</span></label>
|
||||
<select name="satuan" class="form-select @error('satuan') is-invalid @enderror" required>
|
||||
@foreach(['kg' => 'Kg', 'ton' => 'Ton', 'kuintal' => 'Kuintal'] as $value => $label)
|
||||
<option value="{{ $value }}" {{ old('satuan', $produksi->satuan ?? 'kg') == $value ? 'selected' : '' }}>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('satuan')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-md-4 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(['belum_panen' => 'Belum Panen', 'panen_sebagian' => 'Panen Sebagian', 'selesai' => 'Selesai'] as $value => $label)
|
||||
<option value="{{ $value }}" {{ old('status_panen', $produksi->status_panen ?? 'belum_panen') == $value ? 'selected' : '' }}>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('status_panen')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
<div class="col-12 mb-3">
|
||||
<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>
|
||||
@error('catatan')<div class="invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-end">
|
||||
<a href="{{ route('produksi.index') }}" class="btn btn-label-secondary me-2">Batal</a>
|
||||
<button type="submit" class="btn btn-primary"><i class="ti tabler-device-floppy me-1"></i> Simpan</button>
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
@php
|
||||
$lahanOptions = $lahan->map(function ($item) {
|
||||
return [
|
||||
'id' => $item->id,
|
||||
'profile_id' => $item->profile_id,
|
||||
'nama' => $item->nama,
|
||||
];
|
||||
})->values();
|
||||
@endphp
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const profileSelect = document.getElementById('profile_id');
|
||||
const lahanSelect = document.getElementById('lahan_id');
|
||||
const selectedLahanId = "{{ old('lahan_id', $produksi->lahan_id ?? '') }}";
|
||||
const lahanOptions = @json($lahanOptions);
|
||||
|
||||
function renderLahanOptions() {
|
||||
const profileId = profileSelect.value;
|
||||
|
||||
lahanSelect.innerHTML = '';
|
||||
|
||||
if (!profileId) {
|
||||
lahanSelect.disabled = true;
|
||||
lahanSelect.add(new Option('Pilih Petani terlebih dahulu', ''));
|
||||
return;
|
||||
}
|
||||
|
||||
const filteredLahan = lahanOptions.filter((item) => String(item.profile_id) === String(profileId));
|
||||
|
||||
lahanSelect.disabled = false;
|
||||
lahanSelect.add(new Option(filteredLahan.length ? 'Pilih Lahan' : 'Petani ini belum memiliki lahan', ''));
|
||||
|
||||
filteredLahan.forEach((item) => {
|
||||
const option = new Option(item.nama, item.id);
|
||||
option.selected = String(item.id) === String(selectedLahanId);
|
||||
lahanSelect.add(option);
|
||||
});
|
||||
|
||||
if (!filteredLahan.length) {
|
||||
lahanSelect.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
profileSelect.addEventListener('change', function () {
|
||||
renderLahanOptions();
|
||||
lahanSelect.value = '';
|
||||
});
|
||||
|
||||
renderLahanOptions();
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@@ -0,0 +1,17 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="card">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0">Tambah Data Produksi</h5>
|
||||
<a href="{{ route('produksi.index') }}" class="btn btn-sm btn-label-secondary"><i class="ti tabler-arrow-left me-1"></i> Kembali</a>
|
||||
</div>
|
||||
<div class="card-body pt-4">
|
||||
<form action="{{ route('produksi.store') }}" method="POST">
|
||||
@include('produktivitas.produksi._form')
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,17 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="card">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0">Edit Data Produksi</h5>
|
||||
<a href="{{ route('produksi.index') }}" class="btn btn-sm btn-label-secondary"><i class="ti tabler-arrow-left me-1"></i> Kembali</a>
|
||||
</div>
|
||||
<div class="card-body pt-4">
|
||||
<form action="{{ route('produksi.update', $produksi->id) }}" method="POST">
|
||||
@include('produktivitas.produksi._form')
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,131 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
@if(session('success'))
|
||||
<div class="alert alert-success alert-dismissible" role="alert">
|
||||
{{ session('success') }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0">Data Produksi</h5>
|
||||
<a href="{{ route('produksi.create') }}" class="btn btn-sm btn-primary"><i class="ti tabler-plus me-1"></i> Tambah Produksi</a>
|
||||
</div>
|
||||
<div class="card-body border-bottom pt-4">
|
||||
<form method="GET" action="{{ route('produksi.index') }}" class="d-flex justify-content-between align-items-center row gap-3 gap-md-0">
|
||||
<div class="col-md-auto d-flex align-items-center">
|
||||
<label class="me-2 text-nowrap">Show</label>
|
||||
<select name="per_page" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
|
||||
@foreach([10, 25, 50] as $size)
|
||||
<option value="{{ $size }}" {{ request('per_page', 10) == $size ? 'selected' : '' }}>{{ $size }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<label class="ms-2 text-nowrap">entries</label>
|
||||
</div>
|
||||
<div class="col-md-auto d-flex gap-2">
|
||||
<select name="status_panen" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
|
||||
<option value="">Semua Status</option>
|
||||
<option value="belum_panen" {{ request('status_panen') == 'belum_panen' ? 'selected' : '' }}>Belum Panen</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">
|
||||
<input type="text" name="search" class="form-control" placeholder="Cari produksi..." value="{{ request('search') }}">
|
||||
<button type="submit" class="btn btn-outline-primary"><i class="ti tabler-search"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive text-nowrap">
|
||||
<table class="table table-hover">
|
||||
<thead class="border-top">
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Kode / Periode</th>
|
||||
<th>Petani</th>
|
||||
<th>Komoditas</th>
|
||||
<th>Lahan</th>
|
||||
<th>Panen</th>
|
||||
<th>Produktivitas</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($produksi as $index => $item)
|
||||
<tr>
|
||||
<td>{{ $produksi->firstItem() + $index }}</td>
|
||||
<td>
|
||||
<span class="fw-medium">{{ $item->kode_produksi ?? '-' }}</span><br>
|
||||
<small class="text-muted">{{ $item->periode ?? '-' }}</small>
|
||||
</td>
|
||||
<td>{{ $item->profile->nama ?? '-' }}</td>
|
||||
<td>{{ $item->komoditas->nama ?? '-' }}</td>
|
||||
<td>{{ $item->lahan->nama ?? '-' }}</td>
|
||||
<td>{{ $item->jumlah_panen ?? '-' }} {{ $item->jumlah_panen ? $item->satuan : '' }}</td>
|
||||
<td>{{ $item->produktivitas ? $item->produktivitas . ' ' . $item->satuan . '/ha' : '-' }}</td>
|
||||
<td>
|
||||
@php($statusClass = ['belum_panen' => 'secondary', 'panen_sebagian' => 'warning', 'selesai' => 'success'][$item->status_panen] ?? 'secondary')
|
||||
<span class="badge bg-label-{{ $statusClass }}">{{ ucwords(str_replace('_', ' ', $item->status_panen)) }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<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="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $item->id }}" data-nama="{{ $item->kode_produksi ?? $item->komoditas->nama ?? 'Produksi' }}"><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>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="9" class="text-center py-4">Tidak ada data produksi ditemukan.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-footer d-flex justify-content-center justify-content-md-end border-top">
|
||||
{{ $produksi->appends(request()->query())->links('pagination::bootstrap-5') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
const csrfTokenProduksi = "{{ csrf_token() }}";
|
||||
|
||||
$(document).on('click', '.delete-record', function () {
|
||||
const id = $(this).data('id');
|
||||
const name = $(this).data('nama');
|
||||
|
||||
Swal.fire({
|
||||
title: 'Hapus Produksi?',
|
||||
text: `Data "${name}" akan dihapus.`,
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Ya, Hapus!',
|
||||
cancelButtonText: 'Batal',
|
||||
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
|
||||
buttonsStyling: false
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
$.ajax({
|
||||
url: `/produksi/${id}`,
|
||||
type: 'DELETE',
|
||||
headers: { 'X-CSRF-TOKEN': csrfTokenProduksi },
|
||||
success: function (res) {
|
||||
Swal.fire({ icon: 'success', title: 'Terhapus!', text: res.message, showConfirmButton: false, timer: 1500 })
|
||||
.then(() => window.location.reload());
|
||||
},
|
||||
error: function () {
|
||||
Swal.fire({ icon: 'error', title: 'Gagal!', text: 'Terjadi kesalahan saat menghapus data.' });
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@@ -0,0 +1,39 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="card">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0">Detail Produksi</h5>
|
||||
<a href="{{ route('produksi.index') }}" class="btn btn-sm btn-label-secondary"><i class="ti tabler-arrow-left me-1"></i> Kembali</a>
|
||||
</div>
|
||||
<div class="card-body pt-4">
|
||||
<div class="row g-3">
|
||||
@foreach([
|
||||
'Kode Produksi' => $produksi->kode_produksi,
|
||||
'Periode' => $produksi->periode,
|
||||
'Petani' => $produksi->profile->nama ?? '-',
|
||||
'Lahan' => $produksi->lahan->nama ?? '-',
|
||||
'Tanaman' => $produksi->tanaman->nama ?? '-',
|
||||
'Komoditas' => $produksi->komoditas->nama ?? '-',
|
||||
'Tanggal Panen' => $produksi->tanggal_panen ? $produksi->tanggal_panen->format('d-m-Y') : '-',
|
||||
'Luas Tanam' => $produksi->luas_tanam,
|
||||
'Luas Panen' => $produksi->luas_panen,
|
||||
'Jumlah Panen' => $produksi->jumlah_panen ? $produksi->jumlah_panen . ' ' . $produksi->satuan : '-',
|
||||
'Produktivitas' => $produksi->produktivitas ? $produksi->produktivitas . ' ' . $produksi->satuan . '/ha' : '-',
|
||||
'Status Panen' => ucwords(str_replace('_', ' ', $produksi->status_panen)),
|
||||
] as $label => $value)
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-muted">{{ $label }}</label>
|
||||
<div class="fw-medium">{{ $value ?? '-' }}</div>
|
||||
</div>
|
||||
@endforeach
|
||||
<div class="col-12">
|
||||
<label class="form-label text-muted">Catatan</label>
|
||||
<div>{{ $produksi->catatan ?? '-' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -1,6 +1,13 @@
|
||||
@extends('layout.main')
|
||||
|
||||
@section('content')
|
||||
@php
|
||||
$petaniProfiles = $profiles->filter(function ($profile) {
|
||||
$role = $profile->role instanceof \App\Enums\Role ? $profile->role->value : $profile->role;
|
||||
|
||||
return $role === \App\Enums\Role::PETANI->value;
|
||||
});
|
||||
@endphp
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="card">
|
||||
<div class="card-header border-bottom">
|
||||
@@ -39,9 +46,9 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($profiles as $index => $item)
|
||||
@forelse($petaniProfiles as $index => $item)
|
||||
<tr>
|
||||
<td>{{ $profiles->firstItem() + $index }}</td>
|
||||
<td>{{ $profiles->firstItem() + $loop->index }}</td>
|
||||
<td>
|
||||
<span class="text-heading fw-medium">{{ $item->nama }}</span><br>
|
||||
<small class="text-muted">{{ $item->email }}</small>
|
||||
@@ -105,4 +112,4 @@
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@endpush
|
||||
|
||||
+8
-2
@@ -16,8 +16,12 @@ Route::middleware('auth')
|
||||
|
||||
// Home
|
||||
Route::get('/', [App\Http\Controllers\Web\Dashboard\SummaryController::class, 'produktivitas'])->name('dashboard.produktivitas');
|
||||
|
||||
Route::get('/UserProfile', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'index'])->name('userProfile.index');
|
||||
Route::get('/UserProfile/security', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'security'])->name('userProfile.security');
|
||||
Route::get('/UserProfile/activities', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'activities'])->name('userProfile.activities');
|
||||
Route::patch('/UserProfile/password', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'updatePassword'])->name('userProfile.password.update');
|
||||
Route::post('/UserProfile/logout-devices', [App\Http\Controllers\Web\Konfigurasi\ProfileController::class, 'logoutDevices'])->name('userProfile.logoutDevices');
|
||||
|
||||
// User
|
||||
Route::resource('users', App\Http\Controllers\Web\Konfigurasi\UserController::class);
|
||||
Route::patch('/users/{user}/verify', [App\Http\Controllers\Web\Konfigurasi\UserController::class, 'verify'])->name('users.verify');
|
||||
@@ -78,6 +82,8 @@ Route::middleware('auth')
|
||||
Route::delete('/profile/{id}', [App\Http\Controllers\Web\Produktivitas\ProfileController::class, 'destroy'])->name('profile.destroy');
|
||||
|
||||
Route::resource('lahan', App\Http\Controllers\Web\Produktivitas\LahanController::class);
|
||||
Route::resource('produksi', App\Http\Controllers\Web\Produktivitas\ProduksiController::class);
|
||||
Route::resource('kualitas', App\Http\Controllers\Web\Produktivitas\KualitasController::class);
|
||||
|
||||
Route::get('/komoditas', [App\Http\Controllers\Web\Master\KomoditasController::class, 'index'])->name('komoditas.index');
|
||||
Route::post('/komoditas', [App\Http\Controllers\Web\Master\KomoditasController::class, 'store'])->name('komoditas.store');
|
||||
@@ -134,4 +140,4 @@ Route::middleware('auth')
|
||||
Route::resource('framework.transformasi.aktivitas.target', App\Http\Controllers\Web\Program\TargetController::class)->only(['show', 'store', 'update', 'destroy']);
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user