From d51959371c8ebea97cd9f65e7bf45fb435d21059 Mon Sep 17 00:00:00 2001 From: myuqinurrohman Date: Fri, 28 Feb 2025 20:42:45 +0700 Subject: [PATCH] feat: location or lokus --- .../Dashboard/DatatableController.php | 130 ++++++++++++++++++ .../Dashboard/LocationController.php | 84 +++++++++++ .../Dashboard/SubLocationController.php | 102 ++++++++++++++ app/Http/Requests/LocationRequest.php | 41 ++++++ app/Http/Requests/SubLocationRequest.php | 44 ++++++ app/Models/Location.php | 22 +++ app/Models/SubLocation.php | 23 ++++ ...25_02_28_105935_create_locations_table.php | 33 +++++ ...2_28_105943_create_sub_locations_table.php | 35 +++++ database/seeders/LocationSeeder.php | 17 +++ database/seeders/SubLocationSeeder.php | 17 +++ .../dashboard/locations/create.blade.php | 65 +++++++++ .../views/dashboard/locations/edit.blade.php | 66 +++++++++ .../views/dashboard/locations/index.blade.php | 62 +++++++++ .../views/dashboard/locations/show.blade.php | 60 ++++++++ .../sub-classifications/create.blade.php | 2 +- .../sub-classifications/show.blade.php | 2 +- .../dashboard/sub-locations/create.blade.php | 83 +++++++++++ .../dashboard/sub-locations/edit.blade.php | 78 +++++++++++ .../dashboard/sub-locations/index.blade.php | 62 +++++++++ .../dashboard/sub-locations/show.blade.php | 68 +++++++++ .../views/partials/app/datatable.blade.php | 49 +++++++ .../partials/dashboard/sidebar.blade.php | 4 +- routes/web.php | 30 ++++ 24 files changed, 1175 insertions(+), 4 deletions(-) create mode 100644 app/Http/Controllers/Dashboard/LocationController.php create mode 100644 app/Http/Controllers/Dashboard/SubLocationController.php create mode 100644 app/Http/Requests/LocationRequest.php create mode 100644 app/Http/Requests/SubLocationRequest.php create mode 100644 app/Models/Location.php create mode 100644 app/Models/SubLocation.php create mode 100644 database/migrations/2025_02_28_105935_create_locations_table.php create mode 100644 database/migrations/2025_02_28_105943_create_sub_locations_table.php create mode 100644 database/seeders/LocationSeeder.php create mode 100644 database/seeders/SubLocationSeeder.php create mode 100644 resources/views/dashboard/locations/create.blade.php create mode 100644 resources/views/dashboard/locations/edit.blade.php create mode 100644 resources/views/dashboard/locations/index.blade.php create mode 100644 resources/views/dashboard/locations/show.blade.php create mode 100644 resources/views/dashboard/sub-locations/create.blade.php create mode 100644 resources/views/dashboard/sub-locations/edit.blade.php create mode 100644 resources/views/dashboard/sub-locations/index.blade.php create mode 100644 resources/views/dashboard/sub-locations/show.blade.php diff --git a/app/Http/Controllers/Dashboard/DatatableController.php b/app/Http/Controllers/Dashboard/DatatableController.php index b47822e..0a31045 100644 --- a/app/Http/Controllers/Dashboard/DatatableController.php +++ b/app/Http/Controllers/Dashboard/DatatableController.php @@ -7,9 +7,11 @@ use App\Models\Classification; use App\Models\ContentRecap; use App\Models\GovernmentAgency; +use App\Models\Location; use App\Models\News; use App\Models\Role; use App\Models\SubClassification; +use App\Models\SubLocation; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; @@ -149,6 +151,134 @@ public function subClassification(Request $request){ } + public function location(Request $request){ + if ($request->ajax()) { + + $data = Location::with(['subLocations'])->get(); + + return DataTables::of($data) + ->addIndexColumn() + ->addColumn('status', function ($data) { + if ($data->status == '0') { + return 'Nonaktif'; + }else{ + return 'Aktif'; + } + }) + ->addColumn('sub_locations', function ($data) { + $subLocationsCount = $data->subLocations->count(); + + if($subLocationsCount > 0){ + return $subLocationsCount. ' [Lihat]'; + }else{ + return $subLocationsCount; + } + + }) + ->addColumn('action', function ($data) { + $showUrl = route('dashboard.locations.show', ['id' => encrypt_id($data->id)]); + + $addSubLocationUrl = route('dashboard.sub.locations.create', ['location' => $data->slug]); + + $editUrl = route('dashboard.locations.edit', ['id' => encrypt_id($data->id)]); + + $deleteUrl = route('dashboard.locations.destroy', ['id' => encrypt_id($data->id)]); + + $dropdown = ''; + + return $dropdown; + }) + + ->rawColumns(['sub_locations', 'status', 'action']) + ->make(true); + } + + return response()->json(['error' => 'Unauthorized'], 401); + + } + + public function subLocation(Request $request){ + if ($request->ajax()) { + + $locationParam = $request->input('location', null); + + if($locationParam){ + $location = Location::where('slug', '=', $locationParam)->first(); + $data = SubLocation::with(['location'])->where('location_id', '=', $location->id)->get(); + }else{ + $data = SubLocation::with(['location'])->get(); + } + + return DataTables::of($data) + ->addIndexColumn() + ->addColumn('location', function ($data) { + return $data->location->name; + }) + ->addColumn('status', function ($data) { + if ($data->status == '0') { + return 'Nonaktif'; + }else{ + return 'Aktif'; + } + }) + ->addColumn('action', function ($data) { + $showUrl = route('dashboard.sub.locations.show', ['id' => encrypt_id($data->id)]); + + $editUrl = route('dashboard.sub.locations.edit', ['id' => encrypt_id($data->id)]); + + $deleteUrl = route('dashboard.sub.locations.destroy', ['id' => encrypt_id($data->id)]); + + $dropdown = ''; + + return $dropdown; + }) + + ->rawColumns(['status', 'action']) + ->make(true); + } + + return response()->json(['error' => 'Unauthorized'], 401); + + } + public function governmentAgency(Request $request){ if ($request->ajax()) { $data = GovernmentAgency::all(); diff --git a/app/Http/Controllers/Dashboard/LocationController.php b/app/Http/Controllers/Dashboard/LocationController.php new file mode 100644 index 0000000..ab43854 --- /dev/null +++ b/app/Http/Controllers/Dashboard/LocationController.php @@ -0,0 +1,84 @@ + 'Lokus' + ]); + } + + public function create(){ + return view('dashboard.locations.create', [ + 'title' => 'Tambah Lokus' + ]); + } + + public function store(LocationRequest $request){ + $validatedData = $request->validated(); + $validatedData['slug'] = Str::slug($validatedData['name']); + $validatedData['enhancer_id'] = Auth::id(); + + $createdLocation = Location::create($validatedData); + + if($createdLocation){ + return redirect()->back()->with('success-status', 'Berhasil menambahkan lokus.'); + }else{ + return redirect()->back()->with('failed-status', 'Gagal menambahkan lokus.'); + } + } + + public function edit($id){ + $location = Location::findOrFail(decrypt_id($id)); + + return view('dashboard.locations.edit', [ + 'title' => 'Ubah Lokus', + 'location' => $location + ]); + } + + public function update(LocationRequest $request, $id){ + $validatedData = $request->validated(); + $validatedData['slug'] = Str::slug($validatedData['name']); + $validatedData['enhancer_id'] = Auth::id(); + + $location = Location::findOrFail(decrypt_id($id)); + $updatedLocation = $location->update($validatedData); + + if($updatedLocation){ + return redirect()->back()->with('success-status', 'Berhasil mengubah lokus.'); + }else{ + return redirect()->back()->with('failed-status', 'Gagal mengubah lokus.'); + } + } + + public function show($id){ + $location = Location::find(decrypt_id($id)); + + return view('dashboard.locations.show', [ + 'title' => 'Detail Lokus', + 'location' => $location + ]); + } + + public function destroy($id){ + try { + $location = Location::findOrFail(decrypt_id($id)); + + $location->delete(); + + return response()->json(['message' => 'Berhasil menghapus lokus.']); + } catch (\Exception $e) { + return response()->json(['message' => 'Gagal menghapus lokus.'], 500); + } + } +} diff --git a/app/Http/Controllers/Dashboard/SubLocationController.php b/app/Http/Controllers/Dashboard/SubLocationController.php new file mode 100644 index 0000000..2d0d7e2 --- /dev/null +++ b/app/Http/Controllers/Dashboard/SubLocationController.php @@ -0,0 +1,102 @@ + 'Sub Lokus', + 'location' => $request->input('location', null), + ]; + + return view('dashboard.sub-locations.index', $viewData); + } + + public function create(Request $request){ + + $viewData = [ + 'title' => 'Tambah Sub Lokus', + 'fromLocation' => false + ]; + + if($request->has('location')){ + $locationSlug = $request->query('location'); + $viewData['location'] = Location::where('slug', '=', $locationSlug)->first(); + $viewData['fromLocation'] = true; + }else{ + $viewData['locations'] = Location::all(); + } + + return view('dashboard.sub-locations.create', $viewData); + } + + public function store(SubLocationRequest $request){ + $validatedData = $request->validated(); + $validatedData['slug'] = Str::slug($validatedData['name']); + $validatedData['enhancer_id'] = Auth::id(); + + $createdSubLocation = SubLocation::create($validatedData); + + if($createdSubLocation){ + return redirect()->back()->with('success-status', 'Berhasil menambahkan sub lokus.'); + }else{ + return redirect()->back()->with('failed-status', 'Gagal menambahkan sub lokus.'); + } + } + + public function edit($id){ + $subLocation = SubLocation::findOrFail(decrypt_id($id)); + + return view('dashboard.sub-locations.edit', [ + 'title' => 'Ubah Sub Lokus', + 'subLocation' => $subLocation, + 'locations' => Location::all() + ]); + } + + public function update(SubLocationRequest $request, $id){ + $validatedData = $request->validated(); + $validatedData['slug'] = Str::slug($validatedData['name']); + $validatedData['enhancer_id'] = Auth::id(); + + $subLocation = SubLocation::findOrFail(decrypt_id($id)); + $updatedSubLocation = $subLocation->update($validatedData); + + if($updatedSubLocation){ + return redirect()->back()->with('success-status', 'Berhasil mengubah sub lokus.'); + }else{ + return redirect()->back()->with('failed-status', 'Gagal mengubah sub lokus.'); + } + } + + public function show($id){ + $subLocation = SubLocation::with(['location'])->find(decrypt_id($id)); + + return view('dashboard.sub-locations.show', [ + 'title' => 'Detail Sub Lokus', + 'subLocation' => $subLocation, + ]); + } + + public function destroy($id){ + try { + $subLocation = SubLocation::findOrFail(decrypt_id($id)); + + $subLocation->delete(); + + return response()->json(['message' => 'Berhasil menghapus sub lokus.']); + } catch (\Exception $e) { + return response()->json(['message' => 'Gagal menghapus sub lokus.'], 500); + } + } +} diff --git a/app/Http/Requests/LocationRequest.php b/app/Http/Requests/LocationRequest.php new file mode 100644 index 0000000..c119be5 --- /dev/null +++ b/app/Http/Requests/LocationRequest.php @@ -0,0 +1,41 @@ +|string> + */ + public function rules(): array + { + return [ + 'name' => ['required'], + 'status' => ['required', 'in:0,1'], + 'description' => ['nullable'] + ]; + } + + public function messages(): array + { + return [ + 'name.required' => 'Nama lokus harus diisi.', + 'status.required' => 'Status harus dipilih.', + 'status.in' => 'Status harus memiliki nilai aktif atau tidak aktif.', + 'description.nullable' => 'Deskripsi boleh kosong jika tidak diperlukan.', + ]; + } +} diff --git a/app/Http/Requests/SubLocationRequest.php b/app/Http/Requests/SubLocationRequest.php new file mode 100644 index 0000000..bd8480b --- /dev/null +++ b/app/Http/Requests/SubLocationRequest.php @@ -0,0 +1,44 @@ +|string> + */ + public function rules(): array + { + return [ + 'name' => ['required'], + 'location_id' => ['required', 'exists:locations,id'], + 'status' => ['required', 'in:0,1'], + 'description' => ['nullable'] + ]; + } + + public function messages(): array + { + return [ + 'name.required' => 'Nama lokus harus diisi.', + 'location_id.required' => 'Lokus utama harus dipilih.', + 'location_id.exists' => 'Lokus yang dipilih tidak valid.', + 'status.required' => 'Status harus dipilih.', + 'status.in' => 'Status harus bernilai aktif atau tidak aktif.', + 'description.nullable' => 'Deskripsi boleh kosong jika tidak diperlukan.', + ]; + } +} diff --git a/app/Models/Location.php b/app/Models/Location.php new file mode 100644 index 0000000..518e818 --- /dev/null +++ b/app/Models/Location.php @@ -0,0 +1,22 @@ +hasMany(SubLocation::class, 'location_id', 'id'); + } +} diff --git a/app/Models/SubLocation.php b/app/Models/SubLocation.php new file mode 100644 index 0000000..43dfbbc --- /dev/null +++ b/app/Models/SubLocation.php @@ -0,0 +1,23 @@ +belongsTo(Location::class, 'location_id', 'id'); + } +} diff --git a/database/migrations/2025_02_28_105935_create_locations_table.php b/database/migrations/2025_02_28_105935_create_locations_table.php new file mode 100644 index 0000000..14b68d9 --- /dev/null +++ b/database/migrations/2025_02_28_105935_create_locations_table.php @@ -0,0 +1,33 @@ +id(); + $table->string('name'); + $table->string('slug')->unique();; + $table->text('description')->nullable(); + $table->enum('status', ['0', '1'])->default('0'); + $table->unsignedBigInteger('enhancer_id'); + $table->foreign('enhancer_id')->references('id')->on('users'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('locations'); + } +}; diff --git a/database/migrations/2025_02_28_105943_create_sub_locations_table.php b/database/migrations/2025_02_28_105943_create_sub_locations_table.php new file mode 100644 index 0000000..619f7ed --- /dev/null +++ b/database/migrations/2025_02_28_105943_create_sub_locations_table.php @@ -0,0 +1,35 @@ +id(); + $table->string('name'); + $table->string('slug')->unique();; + $table->text('description')->nullable(); + $table->enum('status', ['0', '1'])->default('0'); + $table->unsignedBigInteger('location_id'); + $table->foreign('location_id')->references('id')->on('locations'); + $table->unsignedBigInteger('enhancer_id'); + $table->foreign('enhancer_id')->references('id')->on('users'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('sub_locations'); + } +}; diff --git a/database/seeders/LocationSeeder.php b/database/seeders/LocationSeeder.php new file mode 100644 index 0000000..7e5d433 --- /dev/null +++ b/database/seeders/LocationSeeder.php @@ -0,0 +1,17 @@ + 'locations']) +@include('partials.dashboard.header') + +
+
+
+
+
+
+
+
+
{{$title}}
+
+
+ @csrf +
+
+
+ +
+ +
+ @error('name') + {{$message}} + @enderror +
+
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+
+ Kembali + +
+
+
+
+
+
+
+
+
+
+
+ +@include('partials.dashboard.footer', ['rich_editor' => false]) diff --git a/resources/views/dashboard/locations/edit.blade.php b/resources/views/dashboard/locations/edit.blade.php new file mode 100644 index 0000000..4c50691 --- /dev/null +++ b/resources/views/dashboard/locations/edit.blade.php @@ -0,0 +1,66 @@ +@include('partials.dashboard.head') +@include('partials.dashboard.sidebar', ['page' => 'locations']) +@include('partials.dashboard.header') + +
+
+
+
+
+
+
+
+
{{$title}}
+
+
+ @csrf + @method('put') +
+
+
+ +
+ +
+ @error('name') + {{$message}} + @enderror +
+
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+
+ Kembali + +
+
+
+
+
+
+
+
+
+
+
+ +@include('partials.dashboard.footer', ['rich_editor' => true]) diff --git a/resources/views/dashboard/locations/index.blade.php b/resources/views/dashboard/locations/index.blade.php new file mode 100644 index 0000000..5570074 --- /dev/null +++ b/resources/views/dashboard/locations/index.blade.php @@ -0,0 +1,62 @@ +@include('partials.dashboard.head') +@include('partials.dashboard.sidebar', ['page' => 'locations']) +@include('partials.dashboard.header') + +
+
+
+
+
+
+
+

{{$title}}

+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+ + + + + + + + + + +
NoNamaStatusSub Lokasi
+
+
+
+
+
+
+
+
+ +@include('partials.dashboard.footer' ,['datatable' => 'location']) diff --git a/resources/views/dashboard/locations/show.blade.php b/resources/views/dashboard/locations/show.blade.php new file mode 100644 index 0000000..a30b24a --- /dev/null +++ b/resources/views/dashboard/locations/show.blade.php @@ -0,0 +1,60 @@ +@include('partials.dashboard.head') +@include('partials.dashboard.sidebar', ['page' => 'locations']) +@include('partials.dashboard.header') + +
+
+
+
+
+
+
+
+
{{$title}}
+
+
+ @csrf + @method('put') +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+
{!! $location->description !!}
+
+
+
+
+
+
+ Kembali + Ubah +
+
+
+
+
+
+
+
+
+
+
+ +@include('partials.dashboard.footer', ['rich_editor' => false]) diff --git a/resources/views/dashboard/sub-classifications/create.blade.php b/resources/views/dashboard/sub-classifications/create.blade.php index 030736b..3ce9569 100644 --- a/resources/views/dashboard/sub-classifications/create.blade.php +++ b/resources/views/dashboard/sub-classifications/create.blade.php @@ -19,7 +19,7 @@
- +
@error('name') {{$message}} diff --git a/resources/views/dashboard/sub-classifications/show.blade.php b/resources/views/dashboard/sub-classifications/show.blade.php index 8d7fdc9..9bf59c8 100644 --- a/resources/views/dashboard/sub-classifications/show.blade.php +++ b/resources/views/dashboard/sub-classifications/show.blade.php @@ -20,7 +20,7 @@
- +
diff --git a/resources/views/dashboard/sub-locations/create.blade.php b/resources/views/dashboard/sub-locations/create.blade.php new file mode 100644 index 0000000..ba9f647 --- /dev/null +++ b/resources/views/dashboard/sub-locations/create.blade.php @@ -0,0 +1,83 @@ +@include('partials.dashboard.head') +@include('partials.dashboard.sidebar', ['page' => 'sub_locations']) +@include('partials.dashboard.header') + +
+
+
+
+
+
+
+
+
{{$title}}
+
+
+ @csrf +
+
+
+ +
+ +
+ @error('name') + {{$message}} + @enderror +
+
+
+
+ +
+ @if ($fromLocation) + + @else + + @endif +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+
+ Kembali + +
+
+
+
+
+
+
+
+
+
+
+ +@include('partials.dashboard.footer', ['rich_editor' => true]) diff --git a/resources/views/dashboard/sub-locations/edit.blade.php b/resources/views/dashboard/sub-locations/edit.blade.php new file mode 100644 index 0000000..7b781e2 --- /dev/null +++ b/resources/views/dashboard/sub-locations/edit.blade.php @@ -0,0 +1,78 @@ +@include('partials.dashboard.head') +@include('partials.dashboard.sidebar', ['page' => 'sub_locations']) +@include('partials.dashboard.header') + +
+
+
+
+
+
+
+
+
{{$title}}
+
+
+ @csrf + @method('put') +
+
+
+ +
+ +
+ @error('name') + {{$message}} + @enderror +
+
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+
+ Kembali + +
+
+
+
+
+
+
+
+
+
+
+ +@include('partials.dashboard.footer', ['rich_editor' => true]) diff --git a/resources/views/dashboard/sub-locations/index.blade.php b/resources/views/dashboard/sub-locations/index.blade.php new file mode 100644 index 0000000..b21f826 --- /dev/null +++ b/resources/views/dashboard/sub-locations/index.blade.php @@ -0,0 +1,62 @@ +@include('partials.dashboard.head') +@include('partials.dashboard.sidebar', ['page' => 'sub_locations']) +@include('partials.dashboard.header') + +
+
+
+
+
+
+
+

{{$title}}

+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+ + + + + + + + + + +
NoLokusNamaStatus
+
+
+
+
+
+
+
+
+ +@include('partials.dashboard.footer' ,['datatable' => 'sub_location']) diff --git a/resources/views/dashboard/sub-locations/show.blade.php b/resources/views/dashboard/sub-locations/show.blade.php new file mode 100644 index 0000000..0be8d91 --- /dev/null +++ b/resources/views/dashboard/sub-locations/show.blade.php @@ -0,0 +1,68 @@ +@include('partials.dashboard.head') +@include('partials.dashboard.sidebar', ['page' => 'sub_locations']) +@include('partials.dashboard.header') + +
+
+
+
+
+
+
+
+
{{$title}}
+
+
+ @csrf + @method('put') +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+
{!! $subLocation->description !!}
+
+
+
+
+
+
+ Kembali + Ubah +
+
+
+
+
+
+
+
+
+
+
+ +@include('partials.dashboard.footer', ['rich_editor' => true]) diff --git a/resources/views/partials/app/datatable.blade.php b/resources/views/partials/app/datatable.blade.php index 99334e9..4cb51e1 100644 --- a/resources/views/partials/app/datatable.blade.php +++ b/resources/views/partials/app/datatable.blade.php @@ -69,6 +69,55 @@ @endif +@if ($datatable === 'location') + +@endif + +@if ($datatable === 'sub_location') + +@endif + @if ($datatable === 'government_agency')