Compare commits

..

36 Commits

Author SHA1 Message Date
@jamaludinarifrohman6661
38948b6633 bug-fix: map tourisms 2025-02-25 11:32:39 +07:00
@jamaludinarifrohman6661
8bae33519f feature: sebaran lokasi project pariwisata 2025-02-24 21:47:24 +07:00
@jamaludinarifrohman6661
6865e353e6 feature: first check point 2025-02-24 20:03:36 +07:00
arifal
a7afbd69fb fix conflict spatial-plannings jamal 2025-02-21 09:07:15 +07:00
arifal
1ff5587050 merge conflix spatial-plannings 2025-02-21 08:42:08 +07:00
arifal
9c8a1a3f3f add vite js customers 2025-02-21 00:49:29 +07:00
arifal
5c4be7635b partial update crud customer data 2025-02-21 00:46:33 +07:00
@jamaludinarifrohman6661
ba315b1dee Fix: upload bulk in column date, and fix template 2025-02-20 22:54:41 +07:00
@jamaludinarifrohman6661
33b7131c33 feature: crud spatial planning and fix search in tourism and umkm 2025-02-20 16:16:06 +07:00
arifal
7a56735099 done crud spatial plannings 2025-02-20 15:35:06 +07:00
@jamaludinarifrohman6661
dd331b4a08 create message error validation on advertisementrequest and tourismsrequest 2025-02-20 10:59:32 +07:00
@jamaludinarifrohman6661
dcd93d66e2 fix: change path download template and add template pariwisata 2025-02-20 10:36:56 +07:00
arifal
54146c8c08 partial update spatial plannings crud 2025-02-19 12:08:18 +07:00
arifal
e8da7193ef fix crud users 2025-02-19 11:23:15 +07:00
arifal
006c008542 done dashboard-potential 2025-02-19 07:22:06 +07:00
root
39bb8e6d5f hot fix vite and create view 2025-02-18 23:49:48 +00:00
arifal
7994a62cea change name dashboard 2025-02-19 06:24:44 +07:00
arifal
3a09e2e68a Merge branch 'bug-fix/tourisms' into feat/dashboard-kekurangan-potensi 2025-02-19 06:17:16 +07:00
arifal
116dc1c8c7 add dashboard potential 2025-02-19 06:15:35 +07:00
@jamaludinarifrohman6661
f10bc153b4 fix: tourisms 2025-02-19 01:39:27 +07:00
@jamaludinarifrohman6661
06a3bb8c8b fix:pariwisata and report pariwisata 2025-02-19 01:07:20 +07:00
arifal
6c936d4c14 add more handle if zero devided 2025-02-18 03:40:20 +07:00
arifal
d4d0a485cd fix vite resources 2025-02-18 03:32:00 +07:00
arifal
864fb26471 add local db backup 2025-02-18 02:58:11 +07:00
arifal
fd97a34344 add vite resources 2025-02-18 02:50:34 +07:00
arifal
1dd971fb73 create update tourisms 2025-02-18 02:45:39 +07:00
arifal
aff31e08ef merge feature umkm 2025-02-18 00:46:51 +07:00
@jamaludinarifrohman6661
2fb8aeceaa feature: viewnya ketinggalan 2025-02-18 00:35:50 +07:00
@jamaludinarifrohman6661
ecc243d1cc Upload Pariwisata dan report pariwisata 2025-02-17 23:58:31 +07:00
arifal
beac71d182 add business industry crud 2025-02-17 18:40:00 +07:00
@jamaludinarifrohman6661
8c236c460d feature: umkm crud and add template file for reklame 2025-02-17 13:03:54 +07:00
arifal hidayat
154b7f40df add sync data setting 2025-02-17 01:52:49 +07:00
arifal
59e9431b2d fetch data from data setting and make seeder realisasi terbit, menunggu klik dpmptsp, proses dinas teknis 2025-02-14 18:28:14 +07:00
arifal
074edc607d add hardcode number for realisasi terbit, proses dinas teknis, menunggu klik dashboards 2025-02-14 17:04:49 +07:00
arifal
625d182d81 fix service google sheet, add uemail to profile, fix detail pbg view, backupdb local last migrate, create menu and role request 2025-02-14 16:22:34 +07:00
@jamaludinarifrohman6661
41ddbaef24 feature/create-migration-and-crud-api 2025-02-12 16:46:06 +07:00
239 changed files with 13041 additions and 6492 deletions

View File

@@ -53,7 +53,7 @@ class AdvertisementController extends Controller
$advertisement->village_name = $village ? $village->village_name : null;
$district = DB::table('districts')->where('district_code', $advertisement->district_code)->first();
$advertisement->district_name = $district ? $district->district_name : null;
$advertisement->district_name = $district ? $district->district_name : null;
return $advertisement;
});
@@ -75,10 +75,10 @@ class AdvertisementController extends Controller
{
$data = $request->validated();
// Cari village_code berdasarkan village_name
$village_code = DB::table('villages')->where('village_name', $data['village_name'])->value('village_code');
// Cari district_code berdasarkan district_name
$district_code = DB::table('districts')->where('district_name', $data['district_name'])->value('district_code');
// Cari village_code berdasarkan village_name
$village_code = DB::table('villages')->where('village_name', $data['village_name'])->where('district_code', $district_code)->value('village_code');
// Tambahkan village_code dan district_code ke data
$data['village_code'] = $village_code;
@@ -142,10 +142,10 @@ class AdvertisementController extends Controller
{
$data = $request->validated();
// Cari village_code berdasarkan village_name
$village_code = DB::table('villages')->where('village_name', $data['village_name'])->value('village_code');
// Cari district_code berdasarkan district_name
$district_code = DB::table('districts')->where('district_name', $data['district_name'])->value('district_code');
// Cari village_code berdasarkan village_name
$village_code = DB::table('villages')->where('village_name', $data['village_name'])->where('district_code', $district_code)->value('village_code');
// Tambahkan village_code dan district_code ke data
$data['village_code'] = $village_code;
@@ -196,4 +196,17 @@ class AdvertisementController extends Controller
return response()->json($results);
}
public function downloadExcelAdvertisement()
{
$filePath = public_path('templates/template_reklame.xlsx');
// Cek apakah file ada
if (!file_exists($filePath)) {
return response()-> json(['message' => 'File tidak ditemukan!'], Response::HTTP_NOT_FOUND);
}
// Return file to download
return response()->download($filePath);
}
}

View File

@@ -0,0 +1,120 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\BusinessIndustryRequest;
use App\Imports\BusinessIndustriesImport;
use App\Models\BusinessOrIndustry;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use \Illuminate\Support\Facades\Validator;
class BusinessOrIndustriesController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$query = BusinessOrIndustry::query()->orderBy('id', 'desc');
if ($request->has("search") && !empty($request->get("search"))) {
$search = $request->get("search");
info($request); // Debugging log
$query->where(function ($q) use ($search) {
$q->where("nop", "LIKE", "%{$search}%")
->orWhere("nama_kecamatan", "LIKE", "%{$search}%")
->orWhere("nama_kelurahan", "LIKE", "%{$search}%");
});
}
return response()->json($query->paginate());
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(BusinessIndustryRequest $request, string $id)
{
try{
$data = BusinessOrIndustry::findOrFail($id);
$data->update($request->validated());
return response()->json(['message' => 'Data updated successfully.'], 200);
}catch(\Exception $e){
\Log::error($e->getMessage());
return response()->json(['message' => 'Failed to update data'],500);
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
try{
$data = BusinessOrIndustry::findOrFail($id);
$data->delete();
return response()->json(['message' => 'Data deleted successfully.'], 200);
}catch(\Exception $e){
\Log::error($e->getMessage());
return response()->json(['message' => 'Failed to delete data'],500);
}
}
public function upload(Request $request){
if ($request->hasFile('file')) {
$file = $request->file('file');
}
// Validasi file
$validator = Validator::make($request->all(), [
'file' => 'required|mimes:xlsx,xls|max:102400', // Max 100MB
]);
if ($validator->fails()) {
return response()->json([
'message' => 'File validation failed.',
'errors' => $validator->errors()
], 400);
}
try {
// Ambil file dari request
$file = $request->file('file');
// Menggunakan Laravel Excel untuk mengimpor file
Excel::import(new BusinessIndustriesImport, $file);
// Jika sukses, kembalikan respons sukses
return response()->json([
'message' => 'File uploaded and imported successfully!'
], 200);
} catch (\Exception $e) {
// Jika ada error, kembalikan error response
return response()->json([
'message' => 'Error during file import.',
'error' => $e->getMessage()
], 500);
}
}
}

View File

@@ -0,0 +1,130 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\CustomersRequest;
use App\Http\Requests\ExcelUploadRequest;
use App\Http\Resources\CustomersResource;
use App\Imports\CustomersImport;
use App\Models\Customer;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
class CustomersController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$query = Customer::query()->orderBy('id', 'desc');
if ($request->has('search') &&!empty($request->get('search'))) {
$query = $query->where('nomor_pelanggan', 'LIKE', '%'.$request->get('search').'%')
->orWhere('nama', 'LIKE', '%'.$request->get('search').'%')
->orWhere('kota_palayanan', 'LIKE', '%'.$request->get('search').'%');
}
return CustomersResource::collection($query->paginate());
}
/**
* Store a newly created resource in storage.
*/
public function store(CustomersRequest $request)
{
try{
$customer = Customer::create($request->validated());
return response()->json(['message' => 'Successfully created', new CustomersResource($customer)]);
}catch(\Exception $e){
return response()->json([
'message' => 'Failed to create customer',
'error' => $e->getMessage()
], 500);
}
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
try{
$customer = Customer::find($id);
if($customer){
return new CustomersResource($customer);
} else {
return response()->json(['message' => 'Customer not found'], 404);
}
}catch(\Exception $e){
return response()->json([
'message' => 'Failed to retrieve customer',
'error' => $e->getMessage()
], 500);
}
}
/**
* Update the specified resource in storage.
*/
public function update(CustomersRequest $request, string $id)
{
try{
$customer = Customer::find($id);
if($customer){
$customer->update($request->validated());
return response()->json(['message' => 'Successfully updated', new CustomersResource($customer)]);
} else {
return response()->json(['message' => 'Customer not found'], 404);
}
}catch(\Exception $e) {
return response()->json([
'message' => 'Failed to update customer',
'error' => $e->getMessage()
], 500);
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
try{
$customer = Customer::find($id);
if($customer){
$customer->delete();
return response()->json(['message' => 'Successfully deleted']);
}else {
return response()->json(['message' => 'Customer not found'], 404);
}
}catch(\Exception $e) {
return response()->json([
'message' => 'Failed to delete customer',
'error' => $e->getMessage()
], 500);
}
}
public function upload(ExcelUploadRequest $request){
try{
if(!$request->hasFile('file')){
return response()->json([
'error' => 'No file provided'
], 400);
}
$file = $request->file('file');
Excel::import(new CustomersImport, $file);
return response()->json([
'message' => 'File uploaded successfully',
]);
}catch(\Exception $e){
\Log::info($e->getMessage());
return response()->json([
'error' => 'Failed to upload file',
'message' => $e->getMessage()
], 500);
}
}
}

View File

@@ -6,6 +6,7 @@ use App\Enums\ImportDatasourceStatus;
use App\Http\Controllers\Controller;
use App\Http\Requests\PbgTaskMultiStepRequest;
use App\Http\Resources\PbgTaskResource;
use App\Models\DataSetting;
use App\Models\ImportDatasource;
use App\Models\PbgTask;
use App\Models\PbgTaskGoogleSheet;
@@ -20,9 +21,35 @@ class PbgTaskController extends Controller
public function __construct(GoogleSheetService $googleSheetService){
$this->googleSheetService = $googleSheetService;
}
public function index()
public function index(Request $request)
{
//
info($request);
$isLastUpdated = filter_var($request->query('isLastUpdated', false), FILTER_VALIDATE_BOOLEAN);
$query = PbgTask::query();
if ($isLastUpdated) {
$query->orderBy('updated_at', 'desc');
} else {
$query->where('status', 20);
}
// Ambil maksimal 10 data
$pbg_task = $query->limit(10)->get();
$totalData = $pbg_task->count();
// Tambahkan nomor urut
$data = $pbg_task->map(function ($item, $index) {
return array_merge($item->toArray(), ['no' => $index + 1]);
});
return response()->json([
'data' => $data,
'meta' => [
'total' => $totalData
]
]);
}
/**
@@ -109,18 +136,55 @@ class PbgTaskController extends Controller
}
public function syncPbgFromGoogleSheet(){
$import_datasource = ImportDatasource::create([
"message" => "initialization",
"response_body" => null,
"status" => ImportDatasourceStatus::Processing->value,
]);
try{
$totalRowCount = $this->googleSheetService->getLastRowByColumn("C");
$sheetData = $this->googleSheetService->getSheetDataCollection($totalRowCount);
$sheet_big_data = $this->googleSheetService->get_data_by_sheet();
$data_setting_result = []; // Initialize result storage
$found_section = null; // Track which section is found
foreach ($sheet_big_data as $row) {
// Check for section headers
if (in_array("•PROSES PENERBITAN:", $row)) {
$found_section = "MENUNGGU_KLIK_DPMPTSP";
} elseif (in_array("•BERKAS AKTUAL TERVERIFIKASI DINAS TEKNIS 2024:", $row)) {
$found_section = "REALISASI_TERBIT_PBG";
} elseif (in_array("•TERPROSES DI DPUTR: belum selesai rekomtek'", $row)) {
$found_section = "PROSES_DINAS_TEKNIS";
}
// If a section is found and we reach "Grand Total", save the corresponding values
if ($found_section && isset($row[0]) && trim($row[0]) === "Grand Total") {
if ($found_section === "MENUNGGU_KLIK_DPMPTSP") {
$data_setting_result["MENUNGGU_KLIK_DPMPTSP_COUNT"] = $row[2] ?? null;
$data_setting_result["MENUNGGU_KLIK_DPMPTSP_SUM"] = $row[3] ?? null;
} elseif ($found_section === "REALISASI_TERBIT_PBG") {
$data_setting_result["REALISASI_TERBIT_PBG_COUNT"] = $row[2] ?? null;
$data_setting_result["REALISASI_TERBIT_PBG_SUM"] = $row[4] ?? null;
} elseif ($found_section === "PROSES_DINAS_TEKNIS") {
$data_setting_result["PROSES_DINAS_TEKNIS_COUNT"] = $row[2] ?? null;
$data_setting_result["PROSES_DINAS_TEKNIS_SUM"] = $row[3] ?? null;
}
// Reset section tracking after capturing "Grand Total"
$found_section = null;
}
}
foreach ($data_setting_result as $key => $value) {
DataSetting::updateOrInsert(
["key" => $key], // Find by key
["value" => $value] // Update or insert value
);
}
$mapToUpsert = [];
$count = 0;
$import_datasource = ImportDatasource::create([
"message" => "initialization",
"response_body" => null,
"status" => ImportDatasourceStatus::Processing->value,
]);
foreach($sheetData as $data){
$mapToUpsert[] =
[
@@ -242,7 +306,7 @@ class PbgTaskController extends Controller
$total_data = count($mapToUpsert);
$import_datasource->update([
"message" => "Successfully imported {$total_data}",
"message" => "Successfully processed: {$total_data}",
"status" => ImportDatasourceStatus::Success->value,
]);

View File

@@ -0,0 +1,146 @@
<?php
namespace App\Http\Controllers\Api;
use App\Models\SpatialPlanning;
use Illuminate\Http\Request;
use App\Http\Requests\SpatialPlanningRequest;
use Illuminate\Http\Response;
use App\Http\Controllers\Controller;
use App\Http\Resources\SpatialPlanningResource;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;
use App\Imports\SpatialPlanningImport;
use Illuminate\Support\Facades\Storage;
class SpatialPlanningController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
info($request);
$perPage = $request->input('per_page', 15);
$search = $request->input('search', '');
$query = SpatialPlanning::query();
if ($search) {
$query->where(function ($q) use ($search) {
$q->where('name', 'like', "%$search%")
->orWhere('kbli', 'like', "%$search%")
->orWhere('activities', 'like', "%$search%")
->orWhere('area', 'like', "%$search%")
->orWhere('location', 'like', "%$search%")
->orWhere('number', 'like', "%$search%");
});
}
$spatialPlannings = $query->paginate($perPage);
// Menambhakan nomor urut (No)
$start = ($spatialPlannings->currentPage()-1) * $perPage + 1;
// Tambahkan nomor urut ke dalam data
$data = $spatialPlannings->map(function ($item, $index) use ($start) {
return array_merge($item->toArray(), ['no' => $start + $index]);
});
info($data);
return response()->json([
'data' => $data,
'meta' => [
'total' => $spatialPlannings->total(),
'per_page' => $spatialPlannings->perPage(),
'current_page' => $spatialPlannings->currentPage(),
'last_page'=>$spatialPlannings->lastPage(),
]
]);
}
/**
* Store a newly created resource in storage.
*/
public function store(SpatialPlanningRequest $request): SpatialPlanning
{
$data = $request->validated();
return SpatialPlanning::create($data);
}
/**
* import spatial planning from excel
*/
public function importFromFile(Request $request)
{
info($request);
//validasi file
$validator = Validator::make($request->all(), [
'file' => 'required|mimes:xlsx, xls|max:10240'
]);
if ($validator->fails()) {
return response()->json([
'message'=>'File vaildation failed.',
"errors"=>$validator->errors()
], 400);
}
try {
$file = $request->file('file');
Excel::import(new SpatialPlanningImport, $file);
return response()->json([
'message'=>'File uploaded and imported successfully!'
], 200);
} catch (\Exception $e) {
return response()->json([
'message'=>'Error during file import.',
'error'=>$e->getMessage()
], 500);
}
}
/**
* Display the specified resource.
*/
public function show(SpatialPlanning $spatialPlanning): SpatialPlanning
{
return $spatialPlanning;
}
/**
* Update the specified resource in storage.
*/
public function update(SpatialPlanningRequest $request, SpatialPlanning $spatialPlanning): SpatialPlanning
{
info($request);
$data = $request->validated();
info($data);
$spatialPlanning->update($data);
return $spatialPlanning;
}
public function destroy(SpatialPlanning $spatialPlanning): Response
{
$spatialPlanning->delete();
return response()->noContent();
}
public function downloadExcelSpatialPlanning()
{
$filePath = public_path('templates/template_spatial_planning.xlsx');
info(sprintf("File Path: %s | Exists: %s", $filePath, file_exists($filePath) ? 'Yes' : 'No'));
// Cek apakah file ada
if (!file_exists($filePath)) {
return response()-> json(['message' => 'File tidak ditemukan!'], Response::HTTP_NOT_FOUND);
}
// Return file to download
return response()->download($filePath);
}
}

View File

@@ -0,0 +1,169 @@
<?php
namespace App\Http\Controllers\Api;
use App\Models\Tourism;
use Illuminate\Http\Request;
use App\Http\Requests\TourismRequest;
use Illuminate\Http\Response;
use App\Http\Controllers\Controller;
use App\Http\Resources\TourismResource;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;
use App\Imports\TourismImport;
use Illuminate\Support\Facades\Storage;
class TourismController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$perPage = $request->input('per_page', 15);
$search = $request->input('search', '');
$query = Tourism::query();
if ($search) {
$query->where(function ($q) use ($search) {
$q->where('business_name', 'like', "%$search%")
->orWhere('project_name', 'like', "%$search%")
->orWhere('business_address', 'like', "%$search%");
});
}
$tourisms = $query->paginate($perPage);
$tourisms->getCollection()->transform(function ($tourisms) {
$village = DB::table('villages')->where('village_code', $tourisms->village_code)->first();
$tourisms->village_name = $village ? $village->village_name : null;
$district = DB::table('districts')->where('district_code', $tourisms->district_code)->first();
$tourisms->district_name = $village ? $village->village_name : null;
return $tourisms;
});
$start = ($tourisms->currentPage()-1) * $perPage + 1;
$data = $tourisms->map(function ($item, $index) use ($start) {
return array_merge($item->toArray(), ['no' => $start + $index]);
});
return response()->json([
'data' => $data,
'meta' => [
'total' => $tourisms->total(),
'per_page' => $tourisms->perPage(),
'current_page' => $tourisms->currentPage(),
'last_page'=>$tourisms->lastPage(),
]
]);
}
/**
* Store a newly created resource in storage.
*/
public function store(TourismRequest $request): Tourism
{
$data = $request->validated();
$district_code = DB::table('districts')->where('district_name', $data['district_name'])->value('district_code');
$village_code = DB::table('villages')->where('village_name', $data['village_name'])->where('district_code', $district_code)->value('village_code');
$data['district_code'] = $district_code;
$data['village_code'] = $village_code;
return Tourism::create($data);
}
/**
* Import advertisements from Excel
*/
public function importFromFile(Request $request)
{
//Validasi file
$validator = Validator::make($request->all(), [
'file' => 'required|mimes:xlsx, xls|max:10240'
]);
if ($validator->fails()) {
return response()->json([
'message'=>'File validation failed.',
'errors'=>$validator->errors()
], 400);
}
try {
$file = $request->file('file');
Excel::import(new TourismImport, $file);
return response()->json([
'message'=>'File uploaded and imported successfully!'
], 200);
} catch (\Exception $e) {
return response()->json([
'message'=>'Error during file import.',
'error'=>$e->getMessage()
], 500);
}
}
public function getAllLocation()
{
$locations = Tourism::whereNotNull('longitude')
->whereNotNull('latitude')
->select('project_name', 'longitude', 'latitude')
->get();
return response()->json([
'data' => $locations
]);
}
/**
* Display the specified resource.
*/
public function show(Tourism $tourism): Tourism
{
return $tourism;
}
/**
* Update the specified resource in storage.
*/
public function update(TourismRequest $request, Tourism $tourism): Tourism
{
$data = $request->validated();
// Cari district_code berdasarkan district_name
$district_code = DB::table('districts')->where('district_name', $data['district_name'])->value('district_code');
// Cari village_code berdasarkan village_name
$village_code = DB::table('villages')->where('village_name', $data['village_name'])->where('district_code', $district_code)->value('village_code');
// Tambahkan village_code dan district_code ke data
$data['village_code'] = $village_code;
$data['district_code'] = $district_code;
$tourism->update($data);
return $tourism;
}
public function destroy(Tourism $tourism): Response
{
$tourism->delete();
return response()->noContent();
}
public function downloadExcelTourism()
{
$filePath = public_path('templates/template_pariwisata.xlsx');
info(sprintf("File Path: %s | Exists: %s", $filePath, file_exists($filePath) ? 'Yes' : 'No'));
// Cek apakah file ada
if (!file_exists($filePath)) {
return response()-> json(['message' => 'File tidak ditemukan!'], Response::HTTP_NOT_FOUND);
}
// Return file to download
return response()->download($filePath);
}
}

View File

@@ -0,0 +1,206 @@
<?php
namespace App\Http\Controllers\Api;
use App\Models\Umkm;
use Illuminate\Http\Request;
use App\Http\Requests\UmkmRequest;
use Illuminate\Http\Response;
use App\Http\Controllers\Controller;
use App\Http\Resources\UmkmResource;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;
use App\Imports\UmkmImport;
use Illuminate\Support\Facades\Storage;
class UmkmController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
info($request);
$perPage = $request->input('per_page', 15);
$search = $request->input('search', '');
$query = Umkm::query();
if ($search) {
$query->where(function ($q) use ($search) {
$q->where('business_name', 'like', "%$search%")
->orWhere('business_address', 'like', "%$search%")
->orWhere('business_desc', 'like', "%$search%")
->orWhere('business_id_number', 'like', "%$search%")
->orWhere('owner_id', 'like', "%$search%")
->orWhere('owner_name', 'like', "%$search%");
});
}
$umkm = $query->paginate($perPage);
$umkm->getCollection()->transform(function ($umkm) {
$village = DB::table('villages')->where('village_code', $umkm->village_code)->first();
$umkm->village_name = $village ? $village->village_name : null;
$district = DB::table('districts')->where('district_code', $umkm->district_code)->first();
$umkm->district_name = $district ? $district->district_name : null;
$business_scale = DB::table('business_scale')->where('id', $umkm->business_scale_id)->first();
$umkm->business_scale = $business_scale ? $business_scale->business_scale : null;
$permit_status = DB::table('permit_status')->where('id', $umkm->permit_status_id)->first();
$umkm->permit_status = $permit_status ? $permit_status->permit_status : null;
$business_form = DB::table('business_form')->where('id', $umkm->business_form_id)->first();
$umkm->business_form = $business_form ? $business_form->business_form : null;
return $umkm;
});
$start = ($umkm->currentPage()-1) * $perPage + 1;
$data = $umkm->map(function ($item, $index) use ($start) {
return array_merge($item->toArray(), ['no' => $start + $index]);
});
return response()->json([
'data' => $data,
'meta' => [
'total' => $umkm->total(),
'per_page' => $umkm->perPage(),
'current_page' => $umkm->currentPage(),
'last_page' => $umkm->lastPage(),
]
]);
}
/**
* Store a newly created resource in storage.
*/
public function store(UmkmRequest $request): Umkm
{
info($request);
$data = $request->validated();
// Cari kode berdasarkan nama
$district_code = DB::table('districts')->where('district_name', $data['district_name'])->value('district_code');
$village_code = DB::table('villages')->where('village_name', $data['village_name'])->where('district_code', $district_code)->value('village_code');
$business_scale_id = DB::table('business_scale')->where('id', $data['business_scale_id'])->value('id');
$permit_status_id = DB::table('permit_status')->where('id', $data['permit_status_id'])->value('id');
$business_form_id = DB::table('business_form')->where('id', $data['business_form_id'])->value('id');
info($business_scale_id);
// Update data dengan kode yang ditemukan
$data['village_code'] = $village_code;
$data['district_code'] = $district_code;
$data['land_area'] = (double) $request['land_area'];
$data['business_scale_id'] = (int) $business_scale_id;
$data['permit_status_id'] = (int) $permit_status_id;
$data['business_form_id'] = (int) $business_form_id;
info($data);
// Simpan ke database
return Umkm::create($data);
}
/**
* Import advertisements from Excel or CSV.
*/
public function importFromFile(Request $request)
{
// Validasi file
$validator = Validator::make($request->all(), [
'file' => 'required|mimes:xlsx, xls|max:10240',
]);
if ($validator->fails()) {
return response()->json([
'message' => 'File validation failed.',
'errors' => $validator->errors()
], 400);
}
try {
// Ambil file dari request
$file = $request->file('file');
// Menggunakan Laravel Excel untuk mengimpor file
Excel::import(new UmkmImport, $file);
// Jika sukses, kembalikan response sukses
return response()->json([
'message' => 'File uploaded and imported successfully!'
], 200);
} catch (\Exception $e) {
return response()->json([
'message' => 'Error during file import.',
'error' => $e->getMessage()
], 500);
}
}
/**
* Display the specified resource.
*/
public function show(Umkm $umkm): Umkm
{
return $umkm;
}
/**
* Update the specified resource in storage.
*/
public function update(UmkmRequest $request, Umkm $umkm): Umkm
{
info($request);
$data = $request->validated();
// Cari district_code berdasarkan district_name
$district_code = DB::table('districts')->where('district_name', $data['district_name'])->value('district_code');
// Cari village_code berdasarkan village_name
$village_code = DB::table('villages')->where('village_name', $data['village_name'])->where('district_code', $district_code)->value('village_code');
$business_scale_id = DB::table('business_scale')->where('id', $data['business_scale_id'])->value('id');
$permit_status_id = DB::table('permit_status')->where('id', $data['permit_status_id'])->value('id');
$business_form_id = DB::table('business_form')->where('id', $data['business_form_id'])->value('id');
// Tambahkan village_code dan district_code ke data
$data['village_code'] = $village_code;
$data['district_code'] = $district_code;
$data['land_area'] = (double) $request['land_area'];
$data['business_scale_id'] = (int) $business_scale_id;
$data['permit_status_id'] = (int) $permit_status_id;
$data['business_form_id'] = (int) $business_form_id;
// Log data setelah transformasi
info($data);
$umkm->update($data);
return $umkm;
}
public function destroy(Umkm $umkm): Response
{
$umkm->delete();
return response()->noContent();
}
public function downloadExcelUmkm()
{
$filePath = public_path('templates/template_umkm.xlsx');
// Cek apakah file ada
if (!file_exists($filePath)) {
return response()-> json(['message' => 'File tidak ditemukan!'], Response::HTTP_NOT_FOUND);
}
// Return file to download
return response()->download($filePath);
}
}

View File

@@ -4,9 +4,11 @@ namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Http\Requests\UsersRequest;
use App\Http\Resources\UserResource;
use App\Models\User;
use App\Traits\GlobalApiResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Http\Request;
@@ -35,4 +37,50 @@ class UsersController extends Controller
$request->user()->tokens()->delete();
return response()->json(['message' => 'logged out successfully']);
}
public function store(UsersRequest $request){
$validate_data = $request->validated();
DB::beginTransaction();
try{
$user = User::create([
'name' => $validate_data['name'],
'email' => $validate_data['email'],
'password' => Hash::make($validate_data['password']),
'firstname' => $validate_data['firstname'],
'lastname' => $validate_data['lastname'],
'position' => $validate_data['position'],
]);
$user->roles()->attach((int) $validate_data['role_id']);
DB::commit();
return response()->json(['message' => 'Successfully created'],201);
}catch(\Exception $e){
DB::rollBack();
return response()->json(['message' => $e->getMessage()],500);
};
}
public function update(UsersRequest $request, $id){
try{
$validate_data = $request->validated();
$user = User::findOrFail($id);
DB::beginTransaction();
$user->update([
'name' => $validate_data['name'],
'email' => $validate_data['email'],
'firstname' => $validate_data['firstname'],
'lastname' => $validate_data['lastname'],
'position' => $validate_data['position']
]);
$user->roles()->sync($request->role_id);
DB::commit();
return response()->json(['message' => 'Successfully updated'], 200);
}catch(\Exception $e){
DB::rollBack();
return response()->json(['message' => $e->getMessage()],500);
}
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace App\Http\Controllers;
use App\Models\BusinessOrIndustry;
use Illuminate\Http\Request;
class BusinessOrIndustriesController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
return view('business-industries.index');
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return view("business-industries.create");
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
$data = BusinessOrIndustry::findOrFail($id);
return view('business-industries.edit', compact('data'));
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
//
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Http\Controllers;
use App\Models\Customer;
use Illuminate\Http\Request;
class CustomersController extends Controller
{
public function index()
{
return view('customers.index');
}
public function create()
{
return view('customers.create');
}
public function edit(string $id)
{
$data = Customer::findOrFail($id);
return view('customers.edit', compact('data'));
}
public function upload(){
return view('customers.upload');
}
}

View File

@@ -15,7 +15,8 @@ class BigDataController extends Controller
return view('dashboards.bigdata', compact('latest_created'));
}
public function pbg(){
return view('index');
public function pbg()
{
return view('dashboards.pbg');
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace App\Http\Controllers\Dashboards;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class LackOfPotentialController extends Controller
{
public function lack_of_potential(){
return view('dashboards.lack_of_potential');
}
}

View File

@@ -0,0 +1,125 @@
<?php
namespace App\Http\Controllers\Data;
use App\Http\Controllers\Controller;
use App\Models\SpatialPlanning;
use Illuminate\Http\Request;
class SpatialPlanningController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
return view('data.spatialPlannings.index');
}
/**
* show the form for creating a new resource.
*/
public function bulkCreate()
{
return view('data.spatialPlannings.form-upload');
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
$title = 'Rencana Tata Ruang';
$subtitle = "Create Data";
// Mengambil data untuk dropdown
$dropdownOptions = [];
$fields = $this->getFields();
$fieldTypes = $this->getFieldTypes();
$apiUrl = url('/api/spatial-plannings');
return view('data.spatialPlannings.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
$title = 'Rencana Tata Ruang';
$subtitle = 'Update Data';
$modelInstance = SpatialPlanning::find($id);
// Pastikan model ditemukan
if (!$modelInstance) {
return redirect()->route('spatialPlanning.index') ->with('error', 'Rencana tata ruang tidak ditemukan');
}
$dropdownOptions = [];
$fields = $this->getFields();
$fieldTypes = $this->getFieldTypes();
$apiUrl = url('/api/spatial-plannings');
return view('data.spatialPlannings.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
//
}
private function getFields()
{
return [
"name"=> "Nama",
"kbli"=> "KBLI",
"activities"=> "Kegiatan",
"area"=> "Luas (m2)",
"location"=> "Lokasi",
"number"=> "Nomor",
"date"=> "Tanggal",
];
}
private function getFieldTypes()
{
return [
"name"=> "text",
"kbli"=> "text",
"activities"=> "text",
"area"=> "text",
"location"=> "text",
"number"=> "text",
"date"=> "date",
];
}
}

View File

@@ -0,0 +1,145 @@
<?php
namespace App\Http\Controllers\Data;
use App\Http\Controllers\Controller;
use App\Models\Tourism;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class TourismController extends Controller
{
/**
* Display a listing of the resource
*/
public function index()
{
return view('data.tourisms.index');
}
/**
* show the form for creating a new rsource.
*/
public function bulkCreate()
{
return view('data.tourisms.form-upload');
}
/**
* Show th form for creating a new resource
*/
public function create()
{
$title = 'Pariwisata';
$subtitle = 'Create Data';
// Mengambil data untuk dropdown
$dropdownOptions = [
'village_name' => DB::table('villages')->orderBy('village_name')->pluck('village_name', 'village_code'),
'district_name' => DB::table('districts')->orderBy('district_name')->pluck('district_name', 'district_code')
];
$fields = $this->getFields();
$fieldTypes = $this->getFieldTypes();
$apiUrl = url('/api/tourisms');
return view('data.tourisms.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
}
/**
* show the form for editing the specified resource.
*/
public function edit($id)
{
$title = 'Pariwisata';
$subtitle = 'Update Data';
$modelInstance = Tourism::find($id);
// Pastikan model ditemukan
if (!$modelInstance) {
return redirect()->route('tourisms.index') ->with('error', 'Pariwisata tidak ditemukan');
}
// Mengambil dan memetakan village_name dan district_name
$village = DB::table('villages')->where('village_code', $modelInstance->village_code)->first();
$modelInstance->village_name = $village ? $village->village_name : null;
$district = DB::table('districts')->where('district_code', $modelInstance->district_code)->first();
$modelInstance->district_name = $district ? $district->district_name : null;
$dropdownOptions = [
'village_name' => DB::table('villages')->orderBy('village_name')->pluck('village_name', 'village_code'),
'district_name' => DB::table('districts')->orderBy('district_name')->pluck('district_name', 'district_code')
];
$fields = $this->getFields();
$fieldTypes = $this->getFieldTypes();
$apiUrl = url('/api/tourisms');
return view('data.tourisms.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
}
private function getFields()
{
return [
"project_id" => "ID Proyek",
"project_type_id" => "Jenis Proyek",
"nib" => "NIB",
"business_name" => "Nama Perusahaan",
"oss_publication_date" => "Tanggal Terbit OSS",
"investment_status_description" => "Uraian Status Penanaman Modal",
"business_form" => "Uraian Jenis Perusahaan",
"project_risk" => "Risiko Proyek",
"project_name" => "Nama Proyek",
"business_scale" => "Uraian Skala Usaha",
"business_address" => "Alamat Usaha",
"district_name" => "Kecamatan",
"village_name" => "Desa",
"longitude" => "Longitude",
"latitude" => "Latitude",
"project_submission_date" => "Tanggal Pengajuan Project",
"kbli" => "KBLI",
"kbli_title" => "Judul KBLI",
"supervisory_sector" => "Sektor Pembina",
"user_name" => "Nama User",
"email" => "Email",
"contact" => "Kontak",
"land_area_in_m2" => "Luas Tanah (m2)",
"investment_amount" => "Jumlah Investasi",
"tki" => "TKI",
];
}
private function getFieldTypes()
{
return [
"project_id" => "text",
"project_type_id" => "text",
"nib" => "text",
"business_name" => "text",
"oss_publication_date" => "date",
"investment_status_description" => "text",
"business_form" => "text",
"project_risk" => "text",
"project_name" => "text",
"business_scale" => "text",
"business_address" => "text",
"district_name" => "combobox",
"village_name" => "combobox",
"longitude" => "text",
"latitude" => "text",
"project_submission_date" => "date",
"kbli" => "text",
"kbli_title" => "text",
"supervisory_sector" => "text",
"user_name" => "text",
"email" => "text",
"contact" => "text",
"land_area_in_m2" => "text",
"investment_amount" => "text",
"tki" => "text",
];
}
}

View File

@@ -0,0 +1,149 @@
<?php
namespace App\Http\Controllers\Data;
use App\Http\Controllers\Controller;
use App\Models\Umkm;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class UmkmController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
return view('data.umkm.index');
}
/**
* Show the form for creating a new resource.
*/
public function bulkCreate()
{
return view('data.umkm.form-upload');
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
$title = 'UMKM';
$subtitle = 'Create Data';
// Mengambil data untuk dropdown
$dropdownOptions = [
'village_name' => DB::table('villages')->orderBy('village_name')->pluck('village_name', 'village_code'),
'district_name' => DB::table('districts')->orderBy('district_name')->pluck('district_name', 'district_code'),
'business_scale_id' => DB::table('business_scale')->orderBy('business_scale')->pluck('business_scale', 'id'),
'permit_status_id' => DB::table('permit_status')->orderBy('permit_status')->pluck('permit_status', 'id'),
'business_form_id' => DB::table('business_form')->orderBy('business_form')->pluck('business_form', 'id')
];
$fields = $this->getFields();
$fieldTypes = $this->getFieldTypes();
$apiUrl = url('/api/umkm');
return view('data.umkm.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
}
/**
* Show the form for editing the specified resource.
*/
public function edit($id)
{
$title = 'UMKM';
$subtitle = 'Update Data';
$modelInstance = Umkm::find($id);
// Pastikan model ditemukan
if (!$modelInstance) {
return redirect()->route('umkm.index')->with('error', 'Umkm not found');
}
// Mengambil dan memetakan village_name dan district_name
$village = DB::table('villages')->where('village_code', $modelInstance->village_code)->first();
$modelInstance->village_name = $village ? $village->village_name : null;
$district = DB::table('districts')->where('district_code', $modelInstance->district_code)->first();
$modelInstance->district_name = $district ? $district->district_name : null;
$business_scale = DB::table('business_scale')->where('id', $modelInstance->business_scale_id)->first();
$modelInstance->business_scale_id = $business_scale ? $business_scale->id : null;
$permit_status = DB::table('permit_status')->where('id', $modelInstance->permit_status_id)->first();
$modelInstance->permit_status_id = $permit_status ? $permit_status->id : null;
$business_form = DB::table('business_form')->where('id', $modelInstance->business_form_id)->first();
$modelInstance->business_form_id = $business_form ? $business_form->id : null;
// dd($modelInstance['business_form_id']);
// Mengambil data untuk dropdown
$dropdownOptions = [
'village_name' => DB::table('villages')->orderBy('village_name')->pluck('village_name', 'village_code'),
'district_name' => DB::table('districts')->orderBy('district_name')->pluck('district_name', 'district_code'),
'business_scale_id' => DB::table('business_scale')->orderBy('business_scale')->pluck('business_scale', 'id'),
'permit_status_id' => DB::table('permit_status')->orderBy('permit_status')->pluck('permit_status', 'id'),
'business_form_id' => DB::table('business_form')->orderBy('business_form')->pluck('business_form', 'id')
];
info("AdvertisementController@edit diakses dengan Model Instance: $modelInstance");
$fields = $this->getFields();
$fieldTypes = $this->getFieldTypes();
$apiUrl = url('/api/umkm');
// dd($modelInstance->business_form_id, $dropdownOptions['business_form']);
return view('data.umkm.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
}
private function getFields()
{
return [
"business_name" => "Nama Usaha",
"business_address" => "Alamat Usaha",
"business_desc" => "Deskripsi Usaha",
"business_contact" => "Kontak Usaha",
"business_id_number" => "NIB",
"business_scale_id" => "Skala Usaha",
"owner_id" => "NIK",
"owner_name" => "Nama Pemilik",
"owner_address" => "Alamat Pemilik",
"owner_contact" => "Kontak Pemilik",
"business_type" => "Jenis Usaha",
"district_name" => "Kecamatan",
"village_name" => "Desa",
"number_of_employee" => "Jumlah Karyawan",
"land_area" => "Luas Tanah",
"permit_status_id" => "Ijin Status",
"business_form_id" => "Bisnis Form",
"revenue" => "Omset"
];
}
private function getFieldTypes()
{
return [
"business_name" => "text",
"business_address" => "text",
"business_desc" => "textarea",
"business_contact" => "text",
"business_id_number" => "text",
"business_scale_id" => "select",
"owner_id" => "text",
"owner_name" => "text",
"owner_address" => "text",
"owner_contact" => "text",
"business_type" => "text",
"district_name" => "combobox",
"village_name" => "combobox",
"number_of_employee" => "text",
"land_area" => "text",
"permit_status_id" => "select",
"business_form_id" => "select",
"revenue" => "text"
];
}
}

View File

@@ -3,6 +3,7 @@
namespace App\Http\Controllers\Master;
use App\Http\Controllers\Controller;
use App\Http\Requests\UsersRequest;
use App\Models\Role;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@@ -28,7 +29,7 @@ class UsersController extends Controller
$roles = Role::all();
return view('master.users.create', compact('roles'));
}
public function store(Request $request){
public function store(UsersRequest $request){
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
@@ -39,6 +40,7 @@ class UsersController extends Controller
'role_id' => 'required|exists:roles,id'
]);
DB::beginTransaction();
try{
$user = User::create([

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Http\Requests\MenuRequest;
use App\Models\Menu;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@@ -28,24 +29,12 @@ class MenusController extends Controller
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
public function store(MenuRequest $request)
{
try{
$request->validate([
'name' => 'required|string|max:255',
'url' => 'nullable|string|max:255',
'icon' => 'nullable|string|max:255',
'parent_id' => 'nullable|exists:menus,id', // Ensures it's either null or a valid menu ID
'sort_order' => 'required|integer',
]);
$validated_menu = $request->validated();
DB::beginTransaction();
Menu::create([
'name' => $request->name,
'url' => $request->url,
'icon' => $request->icon,
'parent_id' => $request->parent_id ?? null,
'sort_order' => $request->sort_order,
]);
Menu::create($validated_menu);
DB::commit();
return response()->json(['message' => 'Successfully created'], 200);
}catch(\Exception $e){
@@ -77,21 +66,13 @@ class MenusController extends Controller
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
public function update(MenuRequest $request, string $id)
{
try{
$validateData = $request->validate([
'name' => 'required',
'url'=> 'required',
'icon'=> 'nullable',
'parent_id' => 'nullable',
'sort_order' => 'required',
]);
$validate_menu = $request->validated();
$menu = Menu::findOrFail($id);
DB::beginTransaction();
$menu->update($validateData);
$menu->update($validate_menu);
DB::commit();
return response()->json(['message' => 'Successfully updated'], 200);
}catch(\Exception $e){

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Http\Controllers\Report;
use App\Http\Controllers\Controller;
use App\Models\TourismBasedKBLI;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class ReportTourismController extends Controller
{
/**
* Display a listring of the resource
*/
public function index()
{
$tourismBasedKBLI = TourismBasedKBLI::all();
info($tourismBasedKBLI);
return view('report.tourisms.index', compact('tourismBasedKBLI'));
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Http\Requests\RoleRequest;
use App\Models\Menu;
use App\Models\Role;
use App\Models\RoleMenu;
@@ -31,16 +32,13 @@ class RolesController extends Controller
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
public function store(RoleRequest $request)
{
try{
$request->validate([
"name" => "required|unique:roles,name",
"description" => "nullable",
]);
$validate_role = $request->validated();
DB::beginTransaction();
Role::create($request->all());
Role::create($validate_role);
DB::commit();
return response()->json(['message' => 'Role created successfully'], 201);
}
@@ -70,18 +68,14 @@ class RolesController extends Controller
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
public function update(RoleRequest $request, string $id)
{
try{
$validate_role = $request->validated();
$role = Role::findOrFail($id);
// Validate request data
$validatedData = $request->validate([
'name' => 'required|string|max:255|unique:roles,name,' . $id, // Ensure name is unique except for the current role
'description' => 'nullable|string|max:500',
]);
DB::beginTransaction();
$role->update($validatedData);
$role->update($validate_role);
DB::commit();
return response()->json(['message' => 'Role updated successfully'], 200);
}catch(\Exception $e){
@@ -97,7 +91,7 @@ class RolesController extends Controller
{
try{
DB::beginTransaction();
$deleted = Role::findOrFail($id)->delete();
Role::findOrFail($id)->delete();
DB::commit();
return response()->json(['success' => true, "message" => "Successfully deleted"]);
}catch(\Exception $e){

View File

@@ -40,4 +40,40 @@ class AdvertisementRequest extends FormRequest
'contact' => 'required|string',
];
}
/**
* pesan error validasi
*/
public function messages(): array
{
return [
'no.required' => 'Nomor harus diisi.',
'business_name.required' => 'Nama usaha harus diisi.',
'business_name.string' => 'Nama usaha harus berupa teks.',
'npwpd.required' => 'NPWPD harus diisi.',
'npwpd.string' => 'NPWPD harus berupa teks.',
'advertisement_type.required' => 'Jenis reklame harus diisi.',
'advertisement_type.string' => 'Jenis reklame harus berupa teks.',
'advertisement_content.required' => 'Isi reklame harus diisi.',
'advertisement_content.string' => 'Isi reklame harus berupa teks.',
'business_address.required' => 'Alamat usaha harus diisi.',
'business_address.string' => 'Alamat usaha harus berupa teks.',
'advertisement_location.required' => 'Lokasi reklame harus diisi.',
'advertisement_location.string' => 'Lokasi reklame harus berupa teks.',
'village_name.required' => 'Nama desa harus diisi.',
'district_name.required' => 'Nama kecamatan harus diisi.',
'length.required' => 'Panjang harus diisi.',
'width.required' => 'Lebar harus diisi.',
'viewing_angle.required' => 'Sudut pandang harus diisi.',
'viewing_angle.string' => 'Sudut pandang harus berupa teks.',
'face.required' => 'Jumlah sisi harus diisi.',
'face.string' => 'Jumlah sisi harus berupa teks.',
'area.required' => 'Luas harus diisi.',
'area.string' => 'Luas harus berupa teks.',
'angle.required' => 'Sudut harus diisi.',
'angle.string' => 'Sudut harus berupa teks.',
'contact.required' => 'Kontak harus diisi.',
'contact.string' => 'Kontak harus berupa teks.',
];
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class BusinessIndustryRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'nama_kecamatan' => 'required|string|max:255',
'nama_kelurahan' => 'required|string|max:255',
'nop' => 'required|string|max:255|unique:business_or_industries,nop,' . $this->route('api_business_industry'),
'nama_wajib_pajak' => 'required|string|max:255',
'alamat_wajib_pajak' => 'nullable|string|max:255',
'alamat_objek_pajak' => 'required|string|max:255',
'luas_bumi' => 'required|numeric',
'luas_bangunan' => 'required|numeric',
'njop_bumi' => 'required|numeric',
'njop_bangunan' => 'required|numeric',
'ketetapan' => 'required|string|max:255',
'tahun_pajak' => 'required|integer|min:1900|max:' . date('Y'),
];
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CustomersRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'nomor_pelanggan' => ['required', 'string'],
'kota_pelayanan' => ['required', 'string'],
'nama' => ['required', 'string'],
'alamat' => ['required', 'string'],
'latitude' => ['required', 'numeric', 'between:-90,90'],
'longitude' => ['required', 'numeric', 'between:-180,180'],
];
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ExcelUploadRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
"file" => "required|file|mimes:xlsx,xls|max:102400"
];
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MenuRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => ['required','string','max:255'],
'url' => ['nullable','string','max:255'],
'icon' => ['nullable','string','max:255'],
'parent_id' => ['nullable','exists:menus,id'],
'sort_order' => ['required','integer'],
];
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RoleRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
$roleId = $this->route('role');
return [
'name' => 'required|string|max:255|unique:roles,name,' . ($roleId ?? 'NULL') . ',id',
'description' => 'nullable|string',
];
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SpatialPlanningRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => 'string',
'kbli' => 'string',
'activities' => 'string',
'area' => 'string',
'location' => 'string',
'number' => 'string',
'date' => 'date_format:Y-m-d',
];
}
/**
* Get the validation messages for the defined validation rules.
*
* @return array<string, string>
*/
public function messages(): array
{
return [
'name.string' => 'Kolom Nama harus berupa teks.',
'kbli.string' => 'Kolom KBLI harus berupa teks.',
'activities.string' => 'Kolom Kegiatan harus berupa teks.',
'area.string' => 'Kolom Area harus berupa teks.',
'location.string' => 'Kolom Lokasi harus berupa teks.',
'number.string' => 'Kolom Nomor harus berupa teks.',
'date.date_format' => 'Format tanggal tidak valid, gunakan format Y-m-d H:i:s.',
];
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class SpatialPlanningsRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => ['required','string','max:255'],
'kbli' => ['required','string','max:255'],
'kegiatan' => ['required','string'],
'luas' => ['required','numeric','regex:/^\d{1,16}(\.\d{1,2})?$/'],
'lokasi' => ['required','string'],
'nomor' => ['required','string','max:255',Rule::unique('spatial_plannings')->ignore($this->id)],
'sp_date' => ['required','date'],
];
}
}

View File

@@ -0,0 +1,133 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class TourismRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'project_id' => 'required|string',
'project_type_id' => 'required|string',
'nib' => 'required|string',
'business_name' => 'required|string',
'oss_publication_date' => 'required',
'investment_status_description' => 'required|string',
'business_form' => 'required|string',
'project_risk' => 'required|string',
'project_name' => 'required|string',
'business_scale' => 'required|string',
'business_address' => 'required|string',
'district_name' => 'required',
'village_name' => 'required',
'longitude' => 'required|string',
'latitude' => 'required|string',
'project_submission_date' => 'required',
'kbli' => 'required|string',
'kbli_title' => 'required|string',
'supervisory_sector' => 'required|string',
'user_name' => 'required|string',
'email' => 'required|string',
'contact' => 'required|string',
'land_area_in_m2' => 'required|string',
'investment_amount' => 'required|string',
'tki' => 'required|string',
];
}
/**
* Get the validation messages for the defined validation rules.
*
* @return array<string, string>
*/
public function messages(): array
{
return [
'project_id.required' => 'ID proyek harus diisi.',
'project_id.string' => 'ID proyek harus berupa teks.',
'project_type_id.required' => 'ID tipe proyek harus diisi.',
'project_type_id.string' => 'ID tipe proyek harus berupa teks.',
'nib.required' => 'NIB harus diisi.',
'nib.string' => 'NIB harus berupa teks.',
'business_name.required' => 'Nama usaha harus diisi.',
'business_name.string' => 'Nama usaha harus berupa teks.',
'oss_publication_date.required' => 'Tanggal publikasi OSS harus diisi.',
'investment_status_description.required' => 'Deskripsi status investasi harus diisi.',
'investment_status_description.string' => 'Deskripsi status investasi harus berupa teks.',
'business_form.required' => 'Bentuk usaha harus diisi.',
'business_form.string' => 'Bentuk usaha harus berupa teks.',
'project_risk.required' => 'Risiko proyek harus diisi.',
'project_risk.string' => 'Risiko proyek harus berupa teks.',
'project_name.required' => 'Nama proyek harus diisi.',
'project_name.string' => 'Nama proyek harus berupa teks.',
'business_scale.required' => 'Skala usaha harus diisi.',
'business_scale.string' => 'Skala usaha harus berupa teks.',
'business_address.required' => 'Alamat usaha harus diisi.',
'business_address.string' => 'Alamat usaha harus berupa teks.',
'district_name.required' => 'Nama kecamatan harus diisi.',
'village_name.required' => 'Nama desa harus diisi.',
'longitude.required' => 'Garis bujur harus diisi.',
'longitude.string' => 'Garis bujur harus berupa teks.',
'latitude.required' => 'Garis lintang harus diisi.',
'latitude.string' => 'Garis lintang harus berupa teks.',
'project_submission_date.required' => 'Tanggal pengajuan proyek harus diisi.',
'kbli.required' => 'Kode KBLI harus diisi.',
'kbli.string' => 'Kode KBLI harus berupa teks.',
'kbli_title.required' => 'Judul KBLI harus diisi.',
'kbli_title.string' => 'Judul KBLI harus berupa teks.',
'supervisory_sector.required' => 'Sektor pengawasan harus diisi.',
'supervisory_sector.string' => 'Sektor pengawasan harus berupa teks.',
'user_name.required' => 'Nama pengguna harus diisi.',
'user_name.string' => 'Nama pengguna harus berupa teks.',
'email.required' => 'Email harus diisi.',
'email.string' => 'Email harus berupa teks.',
'contact.required' => 'Kontak harus diisi.',
'contact.string' => 'Kontak harus berupa teks.',
'land_area_in_m2.required' => 'Luas lahan dalam m² harus diisi.',
'land_area_in_m2.string' => 'Luas lahan dalam m² harus berupa teks.',
'investment_amount.required' => 'Jumlah investasi harus diisi.',
'investment_amount.string' => 'Jumlah investasi harus berupa teks.',
'tki.required' => 'Jumlah tenaga kerja Indonesia harus diisi.',
'tki.string' => 'Jumlah tenaga kerja Indonesia harus berupa teks.',
];
}
}

View File

@@ -0,0 +1,106 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UmkmRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'business_name' => 'required|string',
'business_address' => 'required|string',
'business_desc' => 'required|string',
'business_contact' => 'required|string',
'business_id_number' => 'string',
'business_scale_id' => 'required',
'owner_id' => 'required|string',
'owner_name' => 'required|string',
'owner_address' => 'required|string',
'owner_contact' => 'required|string',
'business_type' => 'required|string',
'business_form_id' => 'required|string',
'revenue' => 'required|numeric|between:0,999999999999999999.99',
'village_name' => 'required|string',
'district_name' => 'required',
'number_of_employee' => 'required',
'permit_status_id' => 'required',
'land_area' => 'required|integer|between:0,99999999999',
];
}
/**
* Get the validation messages for the request.
*
* @return array<string, string>
*/
public function messages(): array
{
return [
'business_name.required' => 'Nama usaha wajib diisi.',
'business_name.string' => 'Nama usaha harus berupa teks.',
'business_address.required' => 'Alamat usaha wajib diisi.',
'business_address.string' => 'Alamat usaha harus berupa teks.',
'business_desc.required' => 'Deskripsi usaha wajib diisi.',
'business_desc.string' => 'Deskripsi usaha harus berupa teks.',
'business_contact.required' => 'Kontak usaha wajib diisi.',
'business_contact.string' => 'Kontak usaha harus berupa teks.',
'business_id_number.string' => 'Nomor ID usaha harus berupa teks.',
'business_scale_id.required' => 'Skala usaha wajib diisi.',
'owner_id.required' => 'ID pemilik wajib diisi.',
'owner_id.string' => 'ID pemilik harus berupa teks.',
'owner_name.required' => 'Nama pemilik wajib diisi.',
'owner_name.string' => 'Nama pemilik harus berupa teks.',
'owner_address.required' => 'Alamat pemilik wajib diisi.',
'owner_address.string' => 'Alamat pemilik harus berupa teks.',
'owner_contact.required' => 'Kontak pemilik wajib diisi.',
'owner_contact.string' => 'Kontak pemilik harus berupa teks.',
'business_type.required' => 'Jenis usaha wajib diisi.',
'business_type.string' => 'Jenis usaha harus berupa teks.',
'business_form.required' => 'Bentuk usaha wajib diisi.',
'business_form.string' => 'Bentuk usaha harus berupa teks.',
'revenue.required' => 'Omset wajib diisi.',
'revenue.numeric' => 'Omset harus berupa angka yang valid.',
'revenue.between' => 'Omset harus berada di antara 0 dan 9.999.999.999,99.',
'village_name.required' => 'Nama desa wajib diisi.',
'village_name.string' => 'Nama desa harus berupa teks.',
'district_name.required' => 'Nama distrik wajib diisi.',
'number_of_employee.required' => 'Jumlah karyawan wajib diisi.',
'permit_status_id.required' => 'Status izin wajib diisi.',
'land_area.required' => 'Luas lahan wajib diisi.',
'land_area.integer' => 'Luas lahan harus berupa angka bulat.',
'land_area.between' => 'Luas lahan harus berada di antara 0 dan 99.999.999.999.',
];
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class UsersRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
$userId = $this->route('users'); // Get user ID from route (used in update)
return [
'name' => ['required', 'string', 'max:255'],
'email' => [
'required',
'string',
'email',
'max:255',
Rule::unique('users')->ignore($userId)
],
'password' => [$this->isMethod('post') ? 'required' : 'nullable', 'confirmed', 'max:255'],
'firstname' => ['required', 'string', 'max:255'],
'lastname' => ['required', 'string', 'max:255'],
'position' => ['required', 'string', 'max:255'],
'role_id' => ['required', 'exists:roles,id'],
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class CustomersResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return parent::toArray($request);
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class SpatialPlanningResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return parent::toArray($request);
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class SpatialPlanningsResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return parent::toArray($request);
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class TourismResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return parent::toArray($request);
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class UmkmResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return parent::toArray($request);
}
}

View File

@@ -47,7 +47,7 @@ class AdvertisementImport implements ToCollection
$districtCode = $districts[$districtName] ?? null;
$listTrueVillage = DB::table('villages')
->where('district_code', $districtCode) // Perbaikan pada where()
->where('district_code', $districtCode)
->get()
->mapWithKeys(function ($item) {
return [strtolower(trim($item->village_name)) => [

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Imports;
use App\Models\BusinessOrIndustry;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\ToCollection;
use Illuminate\Support\Collection;
class BusinessIndustriesImport implements ToCollection
{
/**
* @param array $row
*
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function collection(Collection $rows)
{
foreach ($rows->skip(1) as $row){
$clean_nop = preg_replace('/[^A-Za-z0-9]/', '', $row[2]);
if (!BusinessOrIndustry::where('nop', $clean_nop)->exists()) {
BusinessOrIndustry::create([
'nama_kecamatan' => $row[0],
'nama_kelurahan' => $row[1],
'nop' => $clean_nop, // Store cleaned 'nop'
'nama_wajib_pajak' => $row[3],
'alamat_wajib_pajak' => $row[4],
'alamat_objek_pajak' => $row[5],
'luas_bumi' => $row[6],
'luas_bangunan' => $row[7],
'njop_bumi' => $row[8],
'njop_bangunan' => $row[9],
'ketetapan' => $row[10],
'tahun_pajak' => $row[11],
]);
}
}
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace App\Imports;
use App\Models\Customer;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithLimit;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
use Illuminate\Contracts\Queue\ShouldQueue;
use Maatwebsite\Excel\Concerns\WithBatchInserts;
class CustomersImport implements ToCollection, WithMultipleSheets
{
/**
* @param Collection $collection
*/
public function collection(Collection $collection)
{
$batchData = [];
foreach ($collection->skip(1) as $row) {
if (!isset($row[0]) || empty($row[0])) {
continue;
}
$latitude = filter_var($row[4], FILTER_VALIDATE_FLOAT) ? bcadd($row[4], '0', 18) : null;
$longitude = filter_var($row[5], FILTER_VALIDATE_FLOAT) ? bcadd($row[5], '0', 18) : null;
$batchData[] = [
'nomor_pelanggan' => $row[0],
'kota_pelayanan' => $row[1],
'nama' => $row[2],
'alamat' => $row[3],
'latitude' => $latitude,
'longitude' => $longitude,
];
}
if (!empty($batchData)) {
Customer::upsert($batchData, ['nomor_pelanggan'], ['kota_pelayanan', 'nama', 'alamat', 'latitude', 'longitude']);
}
}
public function sheets(): array {
return [
0 => $this
];
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Imports;
use App\Models\SpatialPlanning;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Illuminate\Support\Facades\DB;
use DateTime;
use Carbon\Carbon;
class SpatialPlanningImport implements ToCollection
{
protected static $processed = false;
/**
* Process each row in the file
*/
public function collection(Collection $rows)
{
if (self::$processed) {
return;
}
self::$processed = true;
if ($rows->isEmpty())
{
return;
}
//cari header secara otomatis
$header = $rows->first();
$headerIndex = collect($header)->search(fn($value) => !empty($value));
// Pastikan header ditemukan
if ($headerIndex === false) {
return;
}
foreach ($rows->skip(1) as $row) {
$dateValue = trim($row[7]);
info($dateValue);
$parsedDate = Carbon::createFromFormat('Y-m-d', $dateValue)->format('Y-m-d');
info($parsedDate);
$dataToInsert[] = [
'name'=>$row[1],
'kbli'=>$row[2],
'activities'=>$row[3],
'area'=>$row[4],
'location'=>$row[5],
'number'=>$row[6],
'date'=>$parsedDate,
];
}
if(!empty($dataToInsert)) {
SpatialPlanning::insert($dataToInsert);
} else {
return;
}
}
}

View File

@@ -0,0 +1,113 @@
<?php
namespace App\Imports;
use App\Models\Tourism;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Illuminate\Support\Facades\DB;
use DateTime;
use Carbon\Carbon;
class TourismImport implements ToCollection
{
protected static $processed = false;
/**
* Process each row in the file.
*/
public function collection(Collection $rows)
{
if (self::$processed) {
return;
}
self::$processed = true;
if ($rows->isEmpty())
{
return;
}
// Ambil data districts dengan normalisasi nama
$districts = DB::table('districts')
->get()
->mapWithKeys(function ($item) {
return [strtolower(trim($item->district_name)) => $item->district_code];
})
->toArray();
// Cari header secara otomatis
$header = $rows->first();
$headerIndex = collect($header)->search(fn($value) => !empty($value));
// Pastikan header ditemukan
if ($headerIndex === false) {
return;
}
foreach ($rows->skip(1) as $row) {
// Normalisasi nama kecamatan dan desa
$districtName = strtolower(trim(str_replace('Kecamatan', '', $row[12])));
$villageName = strtolower(trim($row[13]));
// Cari distric_code dari table districts
$districtCode = $districts[$districtName] ?? null;
$listTrueVillage = DB::table('villages')
->where('district_code', $districtCode)
->get()
->mapWithKeys(function ($item) {
return [strtolower(trim($item->village_name)) => [
'village_code' => $item->village_code,
'district_code' => $item->district_code
]];
})
->toArray();
// ambill village code yang village_name sama dengan $villageName
$villageCode = $listTrueVillage[$villageName]['village_code'] ?? '000000';
$excelSerialDate = $row[16];
if (is_numeric($excelSerialDate)) {
$projectSubmissionDate = Carbon::createFromFormat('Y-m-d', '1899-12-30')
->addDays($excelSerialDate)
->format('Y-m-d H:i:s');
} else {
$projectSubmissionDate = Carbon::createFromFormat('m/d/Y', $excelSerialDate)
->format('Y-m-d H:i:s');
}
$dataToInsert[] = [
'project_id' => $row[1],
'project_type_id' => $row[2],
'nib' => $row[3],
'business_name' => $row[4],
'oss_publication_date' => DateTime::createFromFormat('d/m/Y', $row[5]),
'investment_status_description' => $row[6],
'business_form' => $row[7],
'project_risk' => $row[8],
'project_name' => $row[9],
'business_scale' => $row[10],
'business_address' => $row[12],
'district_code' => $districtCode,
'village_code' => $villageCode,
'longitude' => $row[14],
'latitude' => (string) $row[15],
'project_submission_date' => $projectSubmissionDate,
'kbli'=> $row[17],
'kbli_title'=>$row[18],
'supervisory_sector'=>$row[19],
'user_name'=>$row[20],
'email'=>$row[21],
'contact'=>$row[22],
'land_area_in_m2'=>$row[23],
'investment_amount'=>$row[24],
'tki'=>$row[25]
];
}
if(!empty($dataToInsert)) {
Tourism::insert($dataToInsert);
} else {
return;
}
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace App\Imports;
use App\Models\Umkm;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Illuminate\Support\Facades\DB;
class UmkmImport implements ToCollection
{
protected static $processed = false;
/**
* Process each row in the file.
*/
public function collection(Collection $rows)
{
if (self::$processed) {
return;
}
self::$processed = true;
if ($rows->isEmpty())
{
return;
}
// Ambil data districts dengan normalisasi nama
$districts = DB::table('districts')
->get()
->mapWithKeys(function ($item) {
return [strtolower(trim($item->district_name)) => $item->district_code];
})
->toArray();
// Cari header secara otomatis
$header = $rows->first();
$headerIndex = collect($header)->search(fn($value) => !empty($value));
// Pastikan header ditemukan
if ($headerIndex === false) {
return;
}
info($rows);
foreach ($rows->skip(1) as $row) {
// Normalisasi nama kecamatan dan desa
$districtName = strtolower(trim(str_replace('Kecamatan', '', $row[14])));
$villageName = strtolower(trim($row[13]));
// Cari distric_code dari table districts
$districtCode = $districts[$districtName] ?? null;
$listTrueVillage = DB::table('villages')
->where('district_code', $districtCode)
->get()
->mapWithKeys(function ($item) {
return [strtolower(trim($item->village_name)) => [
'village_code' => $item->village_code,
'district_code' => $item->district_code
]];
})
->toArray();
// ambil village code yang village_name sama dengan $villageName
$villageCode = $listTrueVillage[$villageName]['village_code'] ?? '0000';
$dataToInsert[] = [
'business_name' => $row[0],
'business_address' => $row[1],
'business_desc' => $row[2],
'business_contact' => $row[3],
'business_id_number' => $row[4],
'business_scale_id' => $row[5],
'owner_id' => $row[6],
'owner_name' => $row[7],
'owner_address' => $row[8],
'owner_contact' => $row[9],
'business_type' => $row[10],
'business_form_id' => $row[11],
'revenue' => $row[12],
'village_code' => $villageCode,
'district_code' => $districtCode,
'number_of_employee' => $row[15],
'land_area' => $row[16],
'permit_status_id' => $row[17],
];
}
info($dataToInsert);
if (!empty($dataToInsert)) {
Umkm::insert($dataToInsert);
} else {
return;
}
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class BusinessOrIndustry extends Model
{
protected $table = "business_or_industries";
protected $fillable = [
'nama_kecamatan',
'nama_kelurahan',
'nop',
'nama_wajib_pajak',
'alamat_wajib_pajak',
'alamat_objek_pajak',
'luas_bumi',
'luas_bangunan',
'njop_bumi',
'njop_bangunan',
'ketetapan',
'tahun_pajak',
];
}

20
app/Models/Customer.php Normal file
View File

@@ -0,0 +1,20 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
protected $table = 'customers';
protected $fillable = [
'nomor_pelanggan',
'kota_pelayanan',
'nama',
'alamat',
'latitude',
'longitude',
];
}

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Class SpatialPlanning
*
* @property $id
* @property $created_at
* @property $updated_at
* @property $name
* @property $kbli
* @property $activities
* @property $area
* @property $location
* @property $number
* @property $date
*
* @package App
* @mixin \Illuminate\Database\Eloquent\Builder
*/
class SpatialPlanning extends Model
{
protected $perPage = 20;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = ['name', 'kbli', 'activities', 'area', 'location', 'number', 'date'];
}

55
app/Models/Tourism.php Normal file
View File

@@ -0,0 +1,55 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Class Tourism
*
* @property $id
* @property $created_at
* @property $updated_at
* @property $project_id
* @property $project_type_id
* @property $nib
* @property $business_name
* @property $oss_publication_date
* @property $investment_status_description
* @property $business_form
* @property $project_risk
* @property $project_name
* @property $business_scale
* @property $business_address
* @property $district_code
* @property $village_code
* @property $longitude
* @property $latitude
* @property $project_submission_date
* @property $kbli
* @property $kbli_title
* @property $supervisory_sector
* @property $user_name
* @property $email
* @property $contact
* @property $land_area_in_m2
* @property $investment_amount
* @property $tki
*
* @package App
* @mixin \Illuminate\Database\Eloquent\Builder
*/
class Tourism extends Model
{
protected $perPage = 20;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = ['project_id', 'project_type_id', 'nib', 'business_name', 'oss_publication_date', 'investment_status_description', 'business_form', 'project_risk', 'project_name', 'business_scale', 'business_address', 'district_code', 'village_code', 'longitude', 'latitude', 'project_submission_date', 'kbli', 'kbli_title', 'supervisory_sector', 'user_name', 'email', 'contact', 'land_area_in_m2', 'investment_amount', 'tki'];
}

View File

@@ -0,0 +1,14 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class TourismBasedKBLI extends Model
{
protected $table = 'v_tourisms_based_kbli';
protected $primaryKey = null;
public $timestamps = false;
protected $fillable = ['kbli_title', 'total_records'];
}

48
app/Models/Umkm.php Normal file
View File

@@ -0,0 +1,48 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Class Umkm
*
* @property $id
* @property $created_at
* @property $updated_at
* @property $business_name
* @property $business_address
* @property $business_desc
* @property $business_contact
* @property $business_id_number
* @property $business_scale_id
* @property $owner_id
* @property $owner_name
* @property $owner_address
* @property $owner_contact
* @property $business_type
* @property $business_form_id
* @property $revenue
* @property $village_code
* @property $distric_code
* @property $number_of_employee
* @property $land_area
* @property $permit_status_id
*
* @package App
* @mixin \Illuminate\Database\Eloquent\Builder
*/
class Umkm extends Model
{
protected $perPage = 20;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = ['business_name', 'business_address', 'business_desc', 'business_contact', 'business_id_number', 'business_scale_id', 'owner_id', 'owner_name', 'owner_address', 'owner_contact', 'business_type', 'business_form_id', 'revenue', 'village_code', 'district_code', 'number_of_employee', 'land_area', 'permit_status_id'];
}

View File

@@ -34,51 +34,59 @@ class GoogleSheetService
public function getLastRowByColumn($column = "A")
{
// Ambil spreadsheet
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
$sheets = $spreadsheet->getSheets();
if (!empty($sheets)) {
// Ambil nama sheet pertama dengan benar
$firstSheetTitle = $sheets[0]->getProperties()->getTitle();
// ✅ Format range harus benar!
$range = "{$firstSheetTitle}!{$column}:{$column}";
// Ambil data dari kolom yang diminta
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
$values = $response->getValues();
// Cek nilai terakhir yang tidak kosong
$lastRow = 0;
if (!empty($values)) {
foreach ($values as $index => $row) {
if (!empty($row[0])) { // Jika ada data, update lastRow
$lastRow = $index + 1;
try{
// Ambil spreadsheet
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
$sheets = $spreadsheet->getSheets();
if (!empty($sheets)) {
// Ambil nama sheet pertama dengan benar
$firstSheetTitle = $sheets[0]->getProperties()->getTitle();
// ✅ Format range harus benar!
$range = "{$firstSheetTitle}!{$column}:{$column}";
// Ambil data dari kolom yang diminta
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
$values = $response->getValues();
// Cek nilai terakhir yang tidak kosong
$lastRow = 0;
if (!empty($values)) {
foreach ($values as $index => $row) {
if (!empty($row[0])) { // Jika ada data, update lastRow
$lastRow = $index + 1;
}
}
}
return $lastRow;
}
return $lastRow;
return 0;
}catch(\Exception $e){
throw $e;
}
return 0;
}
public function getHeader()
{
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
$sheets = $spreadsheet->getSheets();
// Ambil nama sheet pertama
$firstSheetTitle = $sheets[0]->getProperties()->getTitle();
// Ambil data dari baris pertama (header)
$range = "{$firstSheetTitle}!1:1";
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
$values = $response->getValues();
// Kembalikan header (baris pertama)
return !empty($values) ? $values[0] : [];
try{
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
$sheets = $spreadsheet->getSheets();
// Ambil nama sheet pertama
$firstSheetTitle = $sheets[0]->getProperties()->getTitle();
// Ambil data dari baris pertama (header)
$range = "{$firstSheetTitle}!1:1";
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
$values = $response->getValues();
// Kembalikan header (baris pertama)
return !empty($values) ? $values[0] : [];
}catch(\Exception $e){
throw $e;
}
}
public function getLastColumn()
@@ -99,33 +107,46 @@ class GoogleSheetService
}
public function getSheetDataCollection($totalRow = 10){
try{
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
$sheets = $spreadsheet->getSheets();
$firstSheetTitle = $sheets[0]->getProperties()->getTitle();
$header = $this->getHeader();
$header = array_map(function($columnHeader) {
// Trim spaces first, then replace non-alphanumeric characters with underscores
$columnHeader = trim($columnHeader);
return strtolower(preg_replace('/[^A-Za-z0-9_]/', '_', $columnHeader));
}, $header);
$range = "{$firstSheetTitle}!2:{$totalRow}";
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
$values = $response->getValues();
$mappedData = [];
if (!empty($values)) {
foreach ($values as $row) {
$rowData = [];
foreach ($header as $index => $columnHeader) {
// Map header to the corresponding value from the row
$rowData[$columnHeader] = isset($row[$index]) ? $row[$index] : null;
}
$mappedData[] = $rowData;
}
}
return $mappedData;
}catch(\Exception $e){
throw $e;
}
}
public function get_data_by_sheet($no_sheet = 1){
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
$sheets = $spreadsheet->getSheets();
$firstSheetTitle = $sheets[0]->getProperties()->getTitle();
$header = $this->getHeader();
$header = array_map(function($columnHeader) {
// Trim spaces first, then replace non-alphanumeric characters with underscores
$columnHeader = trim($columnHeader);
return strtolower(preg_replace('/[^A-Za-z0-9_]/', '_', $columnHeader));
}, $header);
$range = "{$firstSheetTitle}!2:{$totalRow}";
$sheetTitle = $sheets[$no_sheet]->getProperties()->getTitle();
$range = "{$sheetTitle}";
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
$values = $response->getValues();
$mappedData = [];
if (!empty($values)) {
foreach ($values as $row) {
$rowData = [];
foreach ($header as $index => $columnHeader) {
// Map header to the corresponding value from the row
$rowData[$columnHeader] = isset($row[$index]) ? $row[$index] : null;
}
$mappedData[] = $rowData;
}
}
return $mappedData;
return!empty($values)? $values : [];
}
}

View File

@@ -29,10 +29,15 @@ class ServiceSIMBG
*/
public function __construct()
{
$this->email = trim((string) GlobalSetting::where('key','SIMBG_EMAIL')->firstOrFail()->value);
$this->password = trim((string) GlobalSetting::where('key','SIMBG_PASSWORD')->firstOrFail()->value);
$this->simbg_host = trim((string)GlobalSetting::where('key','SIMBG_HOST')->firstOrFail()->value);
$this->fetch_per_page = trim((string)GlobalSetting::where('key','FETCH_PER_PAGE')->firstOrFail()->value);
$settings = GlobalSetting::whereIn('key', [
'SIMBG_EMAIL', 'SIMBG_PASSWORD', 'SIMBG_HOST', 'FETCH_PER_PAGE'
])->pluck('value', 'key');
$this->email = trim((string) ($settings['SIMBG_EMAIL'] ?? ""));
$this->password = trim((string) ($settings['SIMBG_PASSWORD'] ?? ""));
$this->simbg_host = trim((string) ($settings['SIMBG_HOST'] ?? ""));
$this->fetch_per_page = trim((string) ($settings['FETCH_PER_PAGE'] ?? ""));
$this->service_client = new ServiceClient($this->simbg_host);
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\View\Components;
use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
class CustomCircle extends Component
{
/**
* Create a new component instance.
*/
public function __construct()
{
//
}
/**
* Get the view / contents that represent the component.
*/
public function render(): View|Closure|string
{
return view('components.custom-circle');
}
}

View File

@@ -19,7 +19,6 @@
},
"require-dev": {
"fakerphp/faker": "^1.23",
"ibex/crud-generator": "^2.1",
"laravel/pail": "^1.1",
"laravel/pint": "^1.13",
"laravel/sail": "^1.26",

View File

@@ -0,0 +1,46 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('umkm', function (Blueprint $table) {
$table->id();
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
$table->string('business_name');
$table->string('business_address');
$table->string('business_desc');
$table->string('business_contact');
$table->string('business_id_number')->nullable();
$table->integer('business_scale_id');
$table->string('owner_id');
$table->string('owner_name');
$table->string('owner_address');
$table->string('owner_contact');
$table->string('business_type');
$table->string('business_form');
$table->decimal('revenue');
$table->string('village_code');
$table->integer('distric_code');
$table->integer('number_of_employee');
$table->float('land_area')->nullable();
$table->integer('permit_status_id');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('umkm');
}
};

View File

@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('business_scale', function (Blueprint $table) {
$table->id();
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
$table->string('business_scale');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('business_scale');
}
};

View File

@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('permit_status', function (Blueprint $table) {
$table->id();
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
$table->string('permit_status');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('permit_status');
}
};

View File

@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('umkm', function (Blueprint $table) {
$table->dropColumn('business_form');
$table->integer('business_form_id')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('umkm', function (Blueprint $table) {
$table->dropColumn('business_form_id');
$table->string('business_form')->nullable();
});
}
};

View File

@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('business_form', function (Blueprint $table) {
$table->id();
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
$table->string('business_form');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('business_form');
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('umkm', function (Blueprint $table) {
$table->renameColumn('distric_code', 'district_code');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('umkm', function (Blueprint $table) {
$table->renameColumn('district_code', 'distric_code');
});
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('umkm', function (Blueprint $table) {
Schema::rename('umkm', 'umkms');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('umkm', function (Blueprint $table) {
Schema::rename('umkm', 'umkms');
});
}
};

View File

@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('umkms', function (Blueprint $table) {
// Mengubah kolom 'revenue' menjadi decimal(20, 2)
$table->decimal('revenue', 20, 2)->change();
// Mengubah kolom 'land_area' menjadi decimal(20, 2)
$table->integer('land_area')->nullable()->change();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('umkm', function (Blueprint $table) {
// Mengembalikan kolom 'revenue' ke decimal default (jika ada)
$table->decimal('revenue')->change();
// Mengembalikan kolom 'land_area' ke tipe sebelumnya (float atau lainnya)
$table->float('land_area')->nullable()->change();
});
}
};

View File

@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('tourism', function (Blueprint $table) {
$table->id();
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
$table->string('business_name');
$table->string('project_name');
$table->string('business_address');
$table->string('village_code');
$table->string('land_area');
$table->string('investment_amount');
$table->string('number_of_employee');
$table->string('business_type_id');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('tourism');
}
};

View File

@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('business_type', function (Blueprint $table) {
$table->id();
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
$table->string('business_type');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('business_type');
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('tourism', function (Blueprint $table) {
$table->string('district_code')->after('business_address');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('tourism', function (Blueprint $table) {
$table->dropColumn('district_code');
});
}
};

View File

@@ -0,0 +1,24 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::rename('tourism', 'tourisms');
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::rename('tourisms', 'tourism');
}
};

View File

@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('tourisms', function (Blueprint $table) {
$table->integer('project_id')->nullable()->after('id');
$table->string('jenis_proyek')->nullable()->after('project_id');
$table->string('nib')->nullable()->after('jenis_proyek');
$table->integer('business_scale_id')->nullable()->after('project_name');
$table->date('terbit_oss')->nullable()->after('business_name');
$table->string('status_penanaman_modal')->nullable()->after('terbit_oss');
$table->string('business_form')->nullable()->after('status_penanaman_modal');
$table->string('uraian_resiko_proyek')->nullable()->after('business_form');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('tourisms', function (Blueprint $table) {
$table->dropColumn(['project_id', 'jenis_proyek', 'nib', 'business_scale_id', 'terbit_oss',
'status_penanaman_modal', 'business_form', 'uraian_resiko_proyek']);
});
}
};

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('tourisms', function (Blueprint $table) {
$table->string('project_id')->change();
$table->integer('district_code')->change();
$table->integer('business_type_id')->change();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('tourisms', function (Blueprint $table) {
$table->integer('project_id')->change();
$table->string('district_code')->change();
$table->string('business_type_id')->change();
});
}
};

View File

@@ -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
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('business_or_industries', function (Blueprint $table) {
$table->id();
$table->string('nama_kecamatan');
$table->string('nama_kelurahan');
$table->string('nop')->unique();
$table->string('nama_wajib_pajak');
$table->text('alamat_wajib_pajak')->nullable();
$table->text('alamat_objek_pajak');
$table->decimal('luas_bumi',20,2)->default(0);
$table->decimal('luas_bangunan',20,2)->default(0);
$table->decimal('njop_bumi',20,2)->default(0);
$table->decimal('njop_bangunan',20,2)->default(0);
$table->decimal('ketetapan',20,2)->default(0);
$table->integer('tahun_pajak');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('business_or_industries');
}
};

View File

@@ -0,0 +1,54 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::dropIfExists('tourisms');
Schema::create('tourisms', function (Blueprint $table) {
$table->id();
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
$table->string('project_id');
$table->string('project_type_id');
$table->string('nib');
$table->string('business_name');
$table->datetime('oss_publication_date');
$table->string('investment_status_description');
$table->string('business_form');
$table->string('project_risk');
$table->string('project_name');
$table->string('business_scale');
$table->string('business_address');
$table->integer('district_code');
$table->integer('village_code');
$table->string('longitude');
$table->string('latitude');
$table->datetime('project_submission_date');
$table->string('kbli');
$table->string('kbli_title');
$table->string('supervisory_sector');
$table->string('user_name');
$table->string('email');
$table->string('contact');
$table->string('land_area_in_m2');
$table->string('investment_amount');
$table->string('tki');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('tourisms');
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('tourisms', function (Blueprint $table) {
$table->string('village_code')->change();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('tourisms', function (Blueprint $table) {
$table->integer('village_code')->change();
});
}
};

View File

@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('spatial_planning', function (Blueprint $table) {
$table->id();
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
$table->string('name')->nullable();
$table->string('kbli')->nullable();
$table->string('activities')->nullable();
$table->string('area')->nullable();
$table->string('location')->nullable();
$table->string('number')->nullable();
$table->dateTime('date')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('spatial_planning');
}
};

View File

@@ -0,0 +1,24 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::rename('spatial_planning', 'spatial_plannings');
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::rename('spatial_plannings', 'spatial_planning');
}
};

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('customers', function (Blueprint $table) {
$table->id();
$table->string('nomor_pelanggan')->unique();
$table->string('kota_pelayanan');
$table->string('nama');
$table->text('alamat');
$table->decimal('latitude', 22,18);
$table->decimal('longitude', 22,18);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('customers');
}
};

View File

@@ -0,0 +1,26 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class BusinessFormSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
DB::table('business_form')->insert([
['business_form' => 'Perseorangan'],
['business_form' => 'Persekutuan'],
['business_form' => 'Koperasi'],
['business_form' => 'CV'],
['business_form' => 'PT'],
['business_form' => 'PTTB'],
['business_form' => 'Perseroan'],
]);
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class BusinessScaleSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
DB::table('business_scale')->insert([
['business_scale' => 'Micro'],
['business_scale' => 'Kecil'],
['business_scale' => 'Menengah'],
]);
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class BusinessTypeSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
DB::table('business_type')->insert([
['business_type' => 'Villas'],
['business_type' => 'Hotels'],
['business_type' => 'Restaurants / Food Stores'],
['business_type' => 'Cafes'],
['business_type' => 'Adventure / Outdoor Activities'],
['business_type' => 'Event Organizers'],
['business_type' => 'Travel & Tours'],
['business_type' => 'Miscellaneous'],
['business_type' => 'Others'],
]);
}
}

View File

@@ -23,7 +23,37 @@ class DataSettingSeeder extends Seeder
"key" => "TATA_RUANG",
"value" => "10000000000",
"type" => "integer"
]
],
[
"key" => "REALISASI_TERBIT_PBG_SUM",
"value" => "1507253788",
"type" => "integer"
],
[
"key" => "REALISASI_TERBIT_PBG_COUNT",
"value" => "88",
"type" => "integer"
],
[
"key" => "MENUNGGU_KLIK_DPMPTSP_SUM",
"value" => "83457536",
"type" => "integer"
],
[
"key" => "MENUNGGU_KLIK_DPMPTSP_COUNT",
"value" => "266",
"type" => "integer"
],
[
"key" => "PROSES_DINAS_TEKNIS_SUM",
"value" => "83457536",
"type" => "integer"
],
[
"key" => "PROSES_DINAS_TEKNIS_COUNT",
"value" => "11",
"type" => "integer"
],
];
foreach ($data_settings as $setting) {

View File

@@ -0,0 +1,22 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class PermitStatusSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
DB::table('permit_status')->insert([
['permit_status' => 'Not Registered'],
['permit_status' => 'Registered'],
['permit_status' => 'Application Process'],
]);
}
}

View File

@@ -67,6 +67,13 @@ class UsersRoleMenuSeeder extends Seeder
"icon" => "mingcute:task-line",
"parent_id" => null,
"sort_order" => 5,
],
[
"name" => "Laporan",
"url" => "/laporan",
"icon" => "mingcute:task-line",
"parent_id" => null,
"sort_order" => 6,
]
];
@@ -84,6 +91,7 @@ class UsersRoleMenuSeeder extends Seeder
$settings = Menu::where('name', 'Settings')->first();
$dataSettings = Menu::where('name', 'Data Settings')->first();
$data = Menu::where('name', 'Data')->first();
$laporan = Menu::where('name', 'Laporan')->first();
// create children menu
$children_menus = [
@@ -101,6 +109,13 @@ class UsersRoleMenuSeeder extends Seeder
"parent_id" => $dashboard->id,
"sort_order" => 2,
],
[
"name" => "Dashboard Potensi",
"url" => "dashboard.lack_of_potential",
"icon" => null,
"parent_id" => $dashboard->id,
"sort_order" => 3,
],
[
"name" => "Users",
"url" => "users.index",
@@ -148,6 +163,48 @@ class UsersRoleMenuSeeder extends Seeder
"url" => "advertisements.index",
"icon" => null,
"parent_id" => $data->id,
"sort_order" => 2,
],
[
"name" => "Usaha atau Industri",
"url" => "business-industries.index",
"icon" => null,
"parent_id" => $data->id,
"sort_order" => 3,
],
[
"name" => "UMKM",
"url" => "umkm.index",
"icon" => null,
"parent_id" => $data->id,
"sort_order" => 4,
],
[
"name" => "Pariwisata",
"url" => "tourisms.index",
"icon" => null,
"parent_id" => $data->id,
"sort_order" => 5,
],
[
"name" => "Tata Ruang",
"url" => "spatial-plannings.index",
"icon" => null,
"parent_id" => $data->id,
"sort_order" => 6,
],
[
"name" => "PDAM",
"url" => "customers",
"icon" => null,
"parent_id" => $data->id,
"sort_order" => 7,
],
[
"name" => "Lap Pariwisata",
"url" => "tourisms.index",
"icon" => null,
"parent_id" => $laporan->id,
"sort_order" => 1,
],
];
@@ -165,6 +222,13 @@ class UsersRoleMenuSeeder extends Seeder
$setting_dashboard = Menu::where('name', 'Setting Dashboard')->first();
$setting_pbg = Menu::where('name', 'PBG')->first();
$reklame = Menu::where('name', 'Reklame')->first();
$businessIndustries = Menu::where('name', 'Usaha atau Industri')->first();
$pariwisata = Menu::where('name', 'Pariwisata')->first();
$laporan_pariwisata = Menu::where('name', 'Lap Pariwisata')->first();
$umkm = Menu::where('name', 'UMKM')->first();
$lack_of_potentials = Menu::where('name', 'Dashboard Potensi')->first();
$spatial_plannings = Menu::where('name', 'Tata Ruang')->first();
$pdam = Menu::where('name', 'PDAM')->first();
// Superadmin gets all menus
$superadmin->menus()->sync([
@@ -174,6 +238,7 @@ class UsersRoleMenuSeeder extends Seeder
$settings->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
$dataSettings->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
$data->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
$laporan->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
// children
$dashboard_pimpinan->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
$dashboard_pbg->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
@@ -184,6 +249,13 @@ class UsersRoleMenuSeeder extends Seeder
$setting_dashboard->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
$setting_pbg->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
$reklame->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
$businessIndustries->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
$pariwisata->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
$laporan_pariwisata->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
$umkm->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
$lack_of_potentials->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
$spatial_plannings->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
$pdam->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
]);
// Admin gets limited menus

View File

@@ -0,0 +1,5 @@
CREATE VIEW business_type_counts AS
SELECT b.business_type, COUNT(t.id) AS count
FROM tourisms t
JOIN business_type b ON t.business_type_id = b.id
GROUP BY b.business_type;

5886
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,35 +1,36 @@
{
"private": true,
"type": "module",
"scripts": {
"build": "vite build",
"dev": "vite"
},
"devDependencies": {
"autoprefixer": "^10.4.20",
"axios": "^1.7.4",
"concurrently": "^9.0.1",
"laravel-vite-plugin": "^1.0",
"postcss": "^8.4.47",
"sass": "^1.81.1",
"tailwindcss": "^3.4.13",
"vite": "^5.0"
},
"dependencies": {
"apexcharts": "^3.44.2",
"big.js": "^6.2.2",
"bootstrap": "^5.3.3",
"countup.js": "^2.3.2",
"dropzone": "^5.9.0",
"flatpickr": "^4.6.13",
"gmaps": "^0.4.25",
"gridjs": "^5.1.0",
"iconify-icon": "^2.1.0",
"jsvectormap": "^1.5.1",
"moment": "^2.29.4",
"node-waves": "^0.7.6",
"quill": "^1.3.7",
"simplebar": "^5.3.9",
"wnumb": "^1.2.0"
}
"private": true,
"type": "module",
"scripts": {
"build": "vite build",
"dev": "vite"
},
"devDependencies": {
"autoprefixer": "^10.4.20",
"axios": "^1.7.4",
"concurrently": "^9.0.1",
"laravel-vite-plugin": "^1.0",
"postcss": "^8.4.47",
"sass": "^1.81.1",
"tailwindcss": "^3.4.13",
"vite": "^5.0"
},
"dependencies": {
"apexcharts": "^3.44.2",
"big.js": "^6.2.2",
"bootstrap": "^5.3.3",
"countup.js": "^2.3.2",
"dropzone": "^5.9.0",
"flatpickr": "^4.6.13",
"gmaps": "^0.4.25",
"gridjs": "^5.1.0",
"iconify-icon": "^2.1.0",
"jsvectormap": "^1.5.1",
"moment": "^2.29.4",
"node-waves": "^0.7.6",
"quill": "^1.3.7",
"simplebar": "^5.3.9",
"sweetalert2": "^11.16.0",
"wnumb": "^1.2.0"
}
}

View File

@@ -1,383 +0,0 @@
{
"__commonjsHelpers-C4iS2aBk.js": {
"file": "assets/_commonjsHelpers-C4iS2aBk.js",
"name": "_commonjsHelpers"
},
"_apexcharts.common-7mov3gaG.js": {
"file": "assets/apexcharts.common-7mov3gaG.js",
"name": "apexcharts.common",
"imports": [
"__commonjsHelpers-C4iS2aBk.js"
]
},
"_global-config-9uDKFQ8j.js": {
"file": "assets/global-config-9uDKFQ8j.js",
"name": "global-config"
},
"_gridjs.umd-BiCNXlqL.js": {
"file": "assets/gridjs.umd-BiCNXlqL.js",
"name": "gridjs.umd",
"imports": [
"__commonjsHelpers-C4iS2aBk.js"
]
},
"_world-BH8KG5u4.js": {
"file": "assets/world-BH8KG5u4.js",
"name": "world",
"imports": [
"__commonjsHelpers-C4iS2aBk.js"
]
},
"node_modules/flatpickr/dist/flatpickr.min.css": {
"file": "assets/flatpickr-CksuuEqD.css",
"src": "node_modules/flatpickr/dist/flatpickr.min.css",
"isEntry": true
},
"node_modules/flatpickr/dist/themes/dark.css": {
"file": "assets/dark-CLxH30By.css",
"src": "node_modules/flatpickr/dist/themes/dark.css",
"isEntry": true
},
"node_modules/gridjs/dist/theme/mermaid.css": {
"file": "assets/mermaid-B5wPN5RC.css",
"src": "node_modules/gridjs/dist/theme/mermaid.css",
"isEntry": true
},
"node_modules/gridjs/dist/theme/mermaid.min.css": {
"file": "assets/mermaid-1KsrsKla.css",
"src": "node_modules/gridjs/dist/theme/mermaid.min.css",
"isEntry": true
},
"node_modules/quill/dist/quill.bubble.css": {
"file": "assets/quill-BzaoboQ1.css",
"src": "node_modules/quill/dist/quill.bubble.css",
"isEntry": true
},
"node_modules/quill/dist/quill.snow.css": {
"file": "assets/quill-D-Ncpkvi.css",
"src": "node_modules/quill/dist/quill.snow.css",
"isEntry": true
},
"resources/fonts/boxicons.eot": {
"file": "assets/boxicons-0t2gX1vj.eot",
"src": "resources/fonts/boxicons.eot"
},
"resources/fonts/boxicons.svg": {
"file": "assets/boxicons-KSR1BgPC.svg",
"src": "resources/fonts/boxicons.svg"
},
"resources/fonts/boxicons.ttf": {
"file": "assets/boxicons-BEZXjQG5.ttf",
"src": "resources/fonts/boxicons.ttf"
},
"resources/fonts/boxicons.woff": {
"file": "assets/boxicons-CEgI8ccS.woff",
"src": "resources/fonts/boxicons.woff"
},
"resources/fonts/boxicons.woff2": {
"file": "assets/boxicons-C7pETWQJ.woff2",
"src": "resources/fonts/boxicons.woff2"
},
"resources/js/app.js": {
"file": "assets/app-Wz_4hh3O.js",
"name": "app",
"src": "resources/js/app.js",
"isEntry": true,
"imports": [
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/config.js": {
"file": "assets/config-DqV4EBmE.js",
"name": "config",
"src": "resources/js/config.js",
"isEntry": true
},
"resources/js/dashboards/bigdata.js": {
"file": "assets/bigdata-DBp18hcY.js",
"name": "bigdata",
"src": "resources/js/dashboards/bigdata.js",
"isEntry": true,
"imports": [
"_global-config-9uDKFQ8j.js"
],
"css": [
"assets/flatpickr-CksuuEqD.css"
]
},
"resources/js/data-settings/create.js": {
"file": "assets/create-C1IbeTHP.js",
"name": "create",
"src": "resources/js/data-settings/create.js",
"isEntry": true
},
"resources/js/data-settings/index.js": {
"file": "assets/index-Bm5aE3Il.js",
"name": "index",
"src": "resources/js/data-settings/index.js",
"isEntry": true,
"imports": [
"_gridjs.umd-BiCNXlqL.js",
"_global-config-9uDKFQ8j.js",
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/data-settings/update.js": {
"file": "assets/update-nNw3P4hj.js",
"name": "update",
"src": "resources/js/data-settings/update.js",
"isEntry": true
},
"resources/js/data/advertisements/data-advertisements.js": {
"file": "assets/data-advertisements-C_ZfB4RA.js",
"name": "data-advertisements",
"src": "resources/js/data/advertisements/data-advertisements.js",
"isEntry": true,
"imports": [
"_gridjs.umd-BiCNXlqL.js",
"_global-config-9uDKFQ8j.js",
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/data/advertisements/form-create-update.js": {
"file": "assets/form-create-update-CyN97GsU.js",
"name": "form-create-update",
"src": "resources/js/data/advertisements/form-create-update.js",
"isEntry": true,
"imports": [
"_global-config-9uDKFQ8j.js"
]
},
"resources/js/master/users/create.js": {
"file": "assets/create-RO4xgm-f.js",
"name": "create",
"src": "resources/js/master/users/create.js",
"isEntry": true
},
"resources/js/master/users/update.js": {
"file": "assets/update-DhoG4v8r.js",
"name": "update",
"src": "resources/js/master/users/update.js",
"isEntry": true
},
"resources/js/master/users/users.js": {
"file": "assets/users-uzXjZCws.js",
"name": "users",
"src": "resources/js/master/users/users.js",
"isEntry": true,
"imports": [
"_gridjs.umd-BiCNXlqL.js",
"_global-config-9uDKFQ8j.js",
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/menus/create.js": {
"file": "assets/create-ChUgh-yc.js",
"name": "create",
"src": "resources/js/menus/create.js",
"isEntry": true
},
"resources/js/menus/index.js": {
"file": "assets/index-qw4Wj-LG.js",
"name": "index",
"src": "resources/js/menus/index.js",
"isEntry": true,
"imports": [
"_gridjs.umd-BiCNXlqL.js",
"_global-config-9uDKFQ8j.js",
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/menus/update.js": {
"file": "assets/update-8JQOGES4.js",
"name": "update",
"src": "resources/js/menus/update.js",
"isEntry": true
},
"resources/js/pages/chart.js": {
"file": "assets/chart-DQBoD9wk.js",
"name": "chart",
"src": "resources/js/pages/chart.js",
"isEntry": true,
"imports": [
"_apexcharts.common-7mov3gaG.js",
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/pages/dashboard.js": {
"file": "assets/dashboard-nkb3Omy9.js",
"name": "dashboard",
"src": "resources/js/pages/dashboard.js",
"isEntry": true,
"imports": [
"_apexcharts.common-7mov3gaG.js",
"_world-BH8KG5u4.js",
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/pages/form-fileupload.js": {
"file": "assets/form-fileupload-mrxZaoHv.js",
"name": "form-fileupload",
"src": "resources/js/pages/form-fileupload.js",
"isEntry": true
},
"resources/js/pages/form-flatepicker.js": {
"file": "assets/form-flatepicker-ChSlk6xC.js",
"name": "form-flatepicker",
"src": "resources/js/pages/form-flatepicker.js",
"isEntry": true,
"imports": [
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/pages/form-quilljs.js": {
"file": "assets/form-quilljs-pSObT4Ti.js",
"name": "form-quilljs",
"src": "resources/js/pages/form-quilljs.js",
"isEntry": true,
"imports": [
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/pages/maps-canada.js": {
"file": "assets/maps-canada-Btz07hSk.js",
"name": "maps-canada",
"src": "resources/js/pages/maps-canada.js",
"isEntry": true
},
"resources/js/pages/maps-google.js": {
"file": "assets/maps-google-KamR_rNw.js",
"name": "maps-google",
"src": "resources/js/pages/maps-google.js",
"isEntry": true,
"imports": [
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/pages/maps-iraq.js": {
"file": "assets/maps-iraq-Blhf9V_8.js",
"name": "maps-iraq",
"src": "resources/js/pages/maps-iraq.js",
"isEntry": true
},
"resources/js/pages/maps-russia.js": {
"file": "assets/maps-russia-C3XucoMP.js",
"name": "maps-russia",
"src": "resources/js/pages/maps-russia.js",
"isEntry": true
},
"resources/js/pages/maps-spain.js": {
"file": "assets/maps-spain-CdBIHB66.js",
"name": "maps-spain",
"src": "resources/js/pages/maps-spain.js",
"isEntry": true
},
"resources/js/pages/maps-vector.js": {
"file": "assets/maps-vector-C2WpvMU7.js",
"name": "maps-vector",
"src": "resources/js/pages/maps-vector.js",
"isEntry": true,
"imports": [
"_world-BH8KG5u4.js",
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/pages/table-gridjs.js": {
"file": "assets/table-gridjs-BQh80cFh.js",
"name": "table-gridjs",
"src": "resources/js/pages/table-gridjs.js",
"isEntry": true,
"imports": [
"_gridjs.umd-BiCNXlqL.js",
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/pbg-task/index.js": {
"file": "assets/index-BW29TEbh.js",
"name": "index",
"src": "resources/js/pbg-task/index.js",
"isEntry": true,
"imports": [
"_gridjs.umd-BiCNXlqL.js",
"_global-config-9uDKFQ8j.js",
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/roles/create.js": {
"file": "assets/create-Dd-lHOwF.js",
"name": "create",
"src": "resources/js/roles/create.js",
"isEntry": true
},
"resources/js/roles/index.js": {
"file": "assets/index-B9clkWIC.js",
"name": "index",
"src": "resources/js/roles/index.js",
"isEntry": true,
"imports": [
"_gridjs.umd-BiCNXlqL.js",
"_global-config-9uDKFQ8j.js",
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/roles/role_menu.js": {
"file": "assets/role_menu-BuFAi1wM.js",
"name": "role_menu",
"src": "resources/js/roles/role_menu.js",
"isEntry": true
},
"resources/js/roles/update.js": {
"file": "assets/update-CapXnAP8.js",
"name": "update",
"src": "resources/js/roles/update.js",
"isEntry": true
},
"resources/js/settings/general/general-settings.js": {
"file": "assets/general-settings-BoJeYQk1.js",
"name": "general-settings",
"src": "resources/js/settings/general/general-settings.js",
"isEntry": true,
"imports": [
"_gridjs.umd-BiCNXlqL.js",
"_global-config-9uDKFQ8j.js",
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/settings/syncronize/syncronize.js": {
"file": "assets/syncronize-DjtcngRb.js",
"name": "syncronize",
"src": "resources/js/settings/syncronize/syncronize.js",
"isEntry": true,
"imports": [
"_gridjs.umd-BiCNXlqL.js",
"_global-config-9uDKFQ8j.js",
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/tables/common-table.js": {
"file": "assets/common-table-KF_NVAIE.js",
"name": "common-table",
"src": "resources/js/tables/common-table.js",
"isEntry": true,
"imports": [
"_gridjs.umd-BiCNXlqL.js",
"_global-config-9uDKFQ8j.js",
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/scss/components/_circle.scss": {
"file": "assets/_circle-ByHaR-XI.css",
"src": "resources/scss/components/_circle.scss",
"isEntry": true
},
"resources/scss/icons.scss": {
"file": "assets/icons-CHxf0fE3.css",
"src": "resources/scss/icons.scss",
"isEntry": true
},
"resources/scss/style.scss": {
"file": "assets/style-DF7fxh2D.css",
"src": "resources/scss/style.scss",
"isEntry": true
}
}

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,125 @@
import { Dropzone } from "dropzone";
import GlobalConfig from "../global-config";
Dropzone.autoDiscover = false;
var previewTemplate,
dropzone,
dropzonePreviewNode = document.querySelector("#dropzone-preview-list");
console.log(previewTemplate);
console.log(dropzone);
console.log(dropzonePreviewNode);
const toastNotification = document.getElementById("toastNotification");
const toast = new bootstrap.Toast(toastNotification);
(dropzonePreviewNode.id = ""),
dropzonePreviewNode &&
((previewTemplate = dropzonePreviewNode.parentNode.innerHTML),
dropzonePreviewNode.parentNode.removeChild(dropzonePreviewNode),
(dropzone = new Dropzone(".dropzone", {
url: `${GlobalConfig.apiHost}/api/api-business-industries/upload`,
method: "post",
acceptedFiles: ".xls,.xlsx", // Use acceptedFiles for better validation
previewTemplate: previewTemplate,
previewsContainer: "#dropzone-preview",
autoProcessQueue: false, // Disable auto post
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
},
init: function () {
// Listen for the success event
this.on("success", function (file, response) {
console.log("File successfully uploaded:", file);
console.log("API Response:", response);
// Show success toast
document.getElementById("toast-message").innerText =
response.message;
toast.show();
document.getElementById("submit-upload").innerHTML =
"Upload Files";
// Tunggu sebentar lalu reload halaman
setTimeout(() => {
window.location.href = "/data/business-industries";
}, 2000);
});
// Listen for the error event
this.on("error", function (file, errorMessage) {
console.error("Error uploading file:", file);
console.error("Error message:", errorMessage);
// Handle the error response
// Show error toast
document.getElementById("toast-message").innerText =
errorMessage.message;
toast.show();
document.getElementById("submit-upload").innerHTML =
"Upload Files";
});
},
})));
// Add event listener to control the submission manually
document.querySelector("#submit-upload").addEventListener("click", function () {
console.log("Ini adalah value dropzone", dropzone.files[0]);
const formData = new FormData();
console.log("Dropzonefiles", dropzone.files);
this.innerHTML =
'<span class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"></span>Loading...';
// Pastikan ada file dalam queue sebelum memprosesnya
if (dropzone.files.length > 0) {
formData.append("file", dropzone.files[0]);
console.log("ini adalah form data on submit", ...formData);
dropzone.processQueue(); // Ini akan manual memicu upload
} else {
// Show error toast when no file is selected
document.getElementById("toast-message").innerText =
"Please add a file first.";
toast.show();
document.getElementById("submit-upload").innerHTML = "Upload Files";
}
});
// Optional: Listen for the 'addedfile' event to log or control file add behavior
dropzone.on("addedfile", function (file) {
console.log("File ditambahkan:", file);
console.log("Nama File:", file.name);
console.log("Tipe File:", file.type);
console.log("Ukuran File:", (file.size / 1024).toFixed(2) + " KB");
});
dropzone.on("complete", function (file) {
dropzone.removeFile(file);
});
// Function to show toast
// function showToast(iconClass, iconColor, message) {
// const toastElement = document.getElementById("toastUploadAdvertisement");
// const toastBody = toastElement.querySelector(".toast-body");
// const toastHeader = toastElement.querySelector(".toast-header");
// // Remove existing icon (if any) before adding the new one
// const existingIcon = toastHeader.querySelector(".bx");
// if (existingIcon) {
// toastHeader.querySelector(".auth-logo").removeChild(existingIcon); // Remove the existing icon
// }
// // Add the new icon to the toast header
// const icon = document.createElement("i");
// icon.classList.add("bx", iconClass);
// icon.style.fontSize = "25px";
// icon.style.color = iconColor;
// toastHeader.querySelector(".auth-logo").appendChild(icon);
// // Set the toast message
// toastBody.textContent = message;
// // Show the toast
// const toast = new bootstrap.Toast(toastElement); // Inisialisasi Bootstrap Toast
// toast.show();
// }

View File

@@ -0,0 +1,260 @@
import { Grid } from "gridjs/dist/gridjs.umd.js";
import gridjs from "gridjs/dist/gridjs.umd.js";
import "gridjs/dist/gridjs.umd.js";
import GlobalConfig from "../global-config.js";
class BusinessIndustries {
constructor() {
this.table = null; // Store Grid.js instance
}
init() {
this.getFetchApiData();
}
getFetchApiData() {
let tableContainer = document.getElementById(
"table-business-industries"
);
if (this.table) {
// If table exists, update its data instead of recreating
this.table
.updateConfig({
server: {
url: `${GlobalConfig.apiHost}/api/api-business-industries`,
credentials: "include",
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
then: (data) =>
data.data.map((item) => [
item.id,
item.nama_kecamatan,
item.nama_kelurahan,
item.nop,
item.nama_wajib_pajak,
item.alamat_wajib_pajak,
item.alamat_objek_pajak,
item.luas_bumi,
item.luas_bangunan,
item.njop_bumi,
item.njop_bangunan,
item.ketetapan,
item.tahun_pajak,
item.created_at,
item.id,
]),
total: (data) => data.total,
},
})
.forceRender();
return;
}
this.table = new Grid({
columns: [
{ name: "ID", width: "80px", hidden: false },
{ name: "Nama Kecamatan", width: "200px" },
{ name: "Nama Kelurahan", width: "200px" },
{ name: "NOP", width: "150px" },
{ name: "Nama Wajib Pajak", width: "250px" },
{ name: "Alamat Wajib Pajak", width: "300px" },
{ name: "Alamat Objek Pajak", width: "300px" },
{ name: "Luas Bumi", width: "150px" },
{ name: "Luas Bangunan", width: "150px" },
{ name: "NJOP Bumi", width: "150px" },
{ name: "NJOP Bangunan", width: "150px" },
{ name: "Ketetapan", width: "150px" },
{ name: "Tahun Pajak", width: "120px" },
{ name: "Created", width: "180px" },
{
name: "Actions",
width: "120px",
formatter: function (cell) {
return gridjs.html(`
<div class="d-flex justify-content-center gap-2">
<a href="/data/business-industries/${cell}/edit" class="btn btn-yellow btn-sm d-inline-flex align-items-center justify-content-center">
<i class='bx bx-edit'></i>
</a>
<button class="btn btn-sm btn-red d-inline-flex align-items-center justify-content-center btn-delete-business-industries" data-id="${cell}">
<i class='bx bxs-trash'></i>
</button>
</div>
`);
},
},
],
search: {
server: {
url: (prev, keyword) => `${prev}?search=${keyword}`,
},
},
pagination: {
limit: 15,
server: {
url: (prev, page) =>
`${prev}${prev.includes("?") ? "&" : "?"}page=${
page + 1
}`,
},
},
sort: true,
server: {
url: `${GlobalConfig.apiHost}/api/api-business-industries`,
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
then: (data) =>
data.data.map((item) => [
item.id,
item.nama_kecamatan,
item.nama_kelurahan,
item.nop,
item.nama_wajib_pajak,
item.alamat_wajib_pajak,
item.alamat_objek_pajak,
item.luas_bumi,
item.luas_bangunan,
item.njop_bumi,
item.njop_bangunan,
item.ketetapan,
item.tahun_pajak,
item.created_at,
item.id, // ID for Actions column
]),
total: (data) => data.total,
},
}).render(tableContainer);
document.addEventListener("click", this.handleDelete.bind(this));
}
handleDelete(event) {
if (event.target.classList.contains("btn-delete-business-industries")) {
event.preventDefault();
const id = event.target.getAttribute("data-id");
let modalElement = document.getElementById("modalConfirmation");
let toastMessage = document.getElementById("toast-message");
if (!modalElement) {
console.error("Modal element not found!");
return;
}
let modal = new bootstrap.Modal(modalElement);
let btnSaveConfirmation = document.getElementById(
"btnSaveConfirmation"
);
let toastElement = document.getElementById("toastNotification");
let toast = new bootstrap.Toast(toastElement);
// Remove previous event listeners to avoid multiple bindings
btnSaveConfirmation.replaceWith(
btnSaveConfirmation.cloneNode(true)
);
btnSaveConfirmation = document.getElementById(
"btnSaveConfirmation"
);
// Set the role ID on the confirm button inside the modal
btnSaveConfirmation.setAttribute("data-business-industries-id", id);
// Show the modal
modal.show();
btnSaveConfirmation.addEventListener("click", async () => {
let deletedId = btnSaveConfirmation.getAttribute(
"data-business-industries-id"
);
try {
let response = await fetch(
`${GlobalConfig.apiHost}/api/api-business-industries/${deletedId}`,
{
method: "DELETE",
credentials: "include",
headers: {
"X-CSRF-TOKEN": document
.querySelector('meta[name="csrf-token"]')
.getAttribute("content"),
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
}
);
if (response.ok) {
let result = await response.json();
toastMessage.innerText =
result.message || "Deleted successfully!";
toast.show();
// Hide modal
modal.hide();
// Refresh Grid.js table
this.refreshDataSettings();
} else {
let error = await response.json();
console.error("Delete failed:", error);
toastMessage.innerText =
error.message || "Delete failed!";
toast.show();
}
} catch (error) {
console.error("Error deleting item:", error);
toastMessage.innerText = "An error occurred!";
toast.show();
}
});
}
}
refreshDataSettings() {
if (this.table) {
this.table
.updateConfig({
server: {
url: `${GlobalConfig.apiHost}/api/api-business-industries`,
credentials: "include",
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
then: (data) =>
data.data.map((item) => [
item.id,
item.nama_kecamatan,
item.nama_kelurahan,
item.nop,
item.nama_wajib_pajak,
item.alamat_wajib_pajak,
item.alamat_objek_pajak,
item.luas_bumi,
item.luas_bangunan,
item.njop_bumi,
item.njop_bangunan,
item.ketetapan,
item.tahun_pajak,
item.created_at,
item.id, // ID for Actions column
]),
total: (data) => data.total,
},
})
.forceRender();
}
}
}
document.addEventListener("DOMContentLoaded", function (e) {
new BusinessIndustries().init();
});

View File

@@ -0,0 +1,79 @@
class UpdateBusinessIndustries {
init() {
this.handleUpdateData();
}
handleUpdateData() {
const form = document.getElementById("formUpdateBusinessIndustries");
const submitButton = document.getElementById(
"btnUpdateBusinessIndustries"
);
const toastNotification = document.getElementById("toastNotification");
const toastBody = document.getElementById("toastBody"); // Add an element inside toast to display messages
const spinner = document.getElementById("spinner");
const toast = new bootstrap.Toast(toastNotification);
if (!submitButton) {
console.error("Error: Submit button not found!");
return;
}
submitButton.addEventListener("click", async function (e) {
e.preventDefault();
// Disable button and show spinner
submitButton.disabled = true;
spinner.classList.remove("d-none");
// Create FormData object
const formData = new FormData(form);
const formObject = {};
formData.forEach((value, key) => {
formObject[key] = value;
});
formData.append("_method", "PUT");
try {
let response = await fetch(form.action, {
method: "POST", // Laravel's update route uses PUT, so adjust accordingly
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
body: JSON.stringify(formObject),
});
let data = await response.json();
if (response.ok) {
// Show success toast
document.getElementById("toast-message").innerText =
data.message;
toast.show();
setTimeout(() => {
window.location.href = "/data/business-industries";
}, 2000);
} else {
// Show error toast with message from API
document.getElementById("toast-message").innerText =
data.message;
toast.show();
submitButton.disabled = false;
spinner.classList.add("d-none");
}
} catch (error) {
// Show error toast for network errors
document.getElementById("toast-message").innerText =
data.message;
toast.show();
submitButton.disabled = false;
spinner.classList.add("d-none");
}
});
}
}
document.addEventListener("DOMContentLoaded", function (e) {
new UpdateBusinessIndustries().init();
});

View File

@@ -0,0 +1,65 @@
class CreateCustomer {
constructor() {
this.initCreateCustomer();
}
initCreateCustomer() {
const toastNotification = document.getElementById("toastNotification");
const toast = new bootstrap.Toast(toastNotification);
document
.getElementById("btnCreateCustomer")
.addEventListener("click", async function () {
let submitButton = this;
let spinner = document.getElementById("spinner");
let form = document.getElementById("formCreateCustomer");
if (!form) {
console.error("Form element not found!");
return;
}
// Get form data
let formData = new FormData(form);
// Disable button and show spinner
submitButton.disabled = true;
spinner.classList.remove("d-none");
try {
let response = await fetch(form.action, {
method: "POST",
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
},
body: formData,
});
if (response.ok) {
let result = await response.json();
document.getElementById("toast-message").innerText =
result.message;
toast.show();
setTimeout(() => {
window.location.href = "/data/customers";
}, 2000);
} else {
let error = await response.json();
document.getElementById("toast-message").innerText =
error.message;
toast.show();
console.error("Error:", error);
}
} catch (error) {
console.error("Request failed:", error);
document.getElementById("toast-message").innerText =
error.message;
toast.show();
}
});
}
}
document.addEventListener("DOMContentLoaded", function (e) {
new CreateCustomer();
});

View File

@@ -0,0 +1,65 @@
class UpdateCustomer {
constructor() {
this.initUpdateSpatial();
}
initUpdateSpatial() {
const toastNotification = document.getElementById("toastNotification");
const toast = new bootstrap.Toast(toastNotification);
document
.getElementById("btnUpdateCustomer")
.addEventListener("click", async function () {
let submitButton = this;
let spinner = document.getElementById("spinner");
let form = document.getElementById("formUpdateCustomer");
if (!form) {
console.error("Form element not found!");
return;
}
// Get form data
let formData = new FormData(form);
// Disable button and show spinner
submitButton.disabled = true;
spinner.classList.remove("d-none");
try {
let response = await fetch(form.action, {
method: "POST",
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
},
body: formData,
});
if (response.ok) {
let result = await response.json();
document.getElementById("toast-message").innerText =
result.message;
toast.show();
setTimeout(() => {
window.location.href = "/data/customers";
}, 2000);
} else {
let error = await response.json();
document.getElementById("toast-message").innerText =
error.message;
toast.show();
console.error("Error:", error);
}
} catch (error) {
console.error("Request failed:", error);
document.getElementById("toast-message").innerText =
error.message;
toast.show();
}
});
}
}
document.addEventListener("DOMContentLoaded", function (e) {
new UpdateCustomer();
});

View File

@@ -0,0 +1,151 @@
import { Grid } from "gridjs/dist/gridjs.umd.js";
import gridjs from "gridjs/dist/gridjs.umd.js";
import "gridjs/dist/gridjs.umd.js";
import GlobalConfig from "../global-config";
import Swal from "sweetalert2";
class Customers {
constructor() {
this.toastMessage = document.getElementById("toast-message");
this.toastElement = document.getElementById("toastNotification");
this.toast = new bootstrap.Toast(this.toastElement);
this.table = null;
// Initialize functions
this.initTableSpatialPlannings();
this.initEvents();
}
initEvents() {
document.body.addEventListener("click", async (event) => {
const deleteButton = event.target.closest(".btn-delete-customers");
if (deleteButton) {
event.preventDefault();
await this.handleDelete(deleteButton);
}
});
}
initTableSpatialPlannings() {
let tableContainer = document.getElementById("table-customers");
// Create a new Grid.js instance only if it doesn't exist
this.table = new Grid({
columns: [
"ID",
"Nomor Pelanggan",
"Nama",
"Kota Pelayanan",
"Alamat",
"Latitude",
"Longitude",
{
name: "Action",
formatter: (cell) =>
gridjs.html(`
<div class="d-flex justify-content-center gap-2">
<a href="/data/customers/${cell}/edit" class="btn btn-yellow btn-sm d-inline-flex align-items-center justify-content-center">
<i class='bx bx-edit'></i>
</a>
<button data-id="${cell}" class="btn btn-sm btn-red btn-delete-customers d-inline-flex align-items-center justify-content-center">
<i class='bx bxs-trash' ></i>
</button>
</div>
`),
},
],
pagination: {
limit: 15,
server: {
url: (prev, page) =>
`${prev}${prev.includes("?") ? "&" : "?"}page=${
page + 1
}`,
},
},
sort: true,
search: {
server: {
url: (prev, keyword) => `${prev}?search=${keyword}`,
},
},
server: {
url: `${GlobalConfig.apiHost}/api/customers`,
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
then: (data) =>
data.data.map((item) => [
item.id,
item.nomor_pelanggan,
item.nama,
item.kota_pelayanan,
item.alamat,
item.latitude,
item.longitude,
item.id,
]),
total: (data) => data.meta.total,
},
}).render(tableContainer);
}
async handleDelete(deleteButton) {
const id = deleteButton.getAttribute("data-id");
const result = await Swal.fire({
title: "Are you sure?",
text: "You won't be able to revert this!",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "Yes, delete it!",
});
if (result.isConfirmed) {
try {
let response = await fetch(
`${GlobalConfig.apiHost}/api/customers/${id}`,
{
method: "DELETE",
credentials: "include",
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
}
);
if (response.ok) {
let result = await response.json();
this.toastMessage.innerText =
result.message || "Deleted successfully!";
this.toast.show();
// Refresh Grid.js table
if (typeof this.table !== "undefined") {
this.table.updateConfig({}).forceRender();
}
} else {
let error = await response.json();
console.error("Delete failed:", error);
this.toastMessage.innerText =
error.message || "Delete failed!";
this.toast.show();
}
} catch (error) {
console.error("Error deleting item:", error);
this.toastMessage.innerText = "An error occurred!";
this.toast.show();
}
}
}
}
document.addEventListener("DOMContentLoaded", function (e) {
new Customers();
});

View File

@@ -0,0 +1,78 @@
import { Dropzone } from "dropzone";
Dropzone.autoDiscover = false;
class UploadCustomers {
constructor() {
this.spatialDropzone = null;
this.formElement = document.getElementById("formUploadCustomers");
this.uploadButton = document.getElementById("submit-upload");
this.spinner = document.getElementById("spinner");
if (!this.formElement) {
console.error("Element formUploadCustomers tidak ditemukan!");
}
}
init() {
this.initDropzone();
this.setupUploadButton();
}
initDropzone() {
const toastNotification = document.getElementById("toastNotification");
const toast = new bootstrap.Toast(toastNotification);
var previewTemplate,
dropzonePreviewNode = document.querySelector(
"#dropzone-preview-list"
);
(dropzonePreviewNode.id = ""),
dropzonePreviewNode &&
((previewTemplate = dropzonePreviewNode.parentNode.innerHTML),
dropzonePreviewNode.parentNode.removeChild(dropzonePreviewNode),
(this.spatialDropzone = new Dropzone(".dropzone", {
url: this.formElement.action,
method: "post",
acceptedFiles: ".xls,.xlsx",
previewTemplate: previewTemplate,
previewsContainer: "#dropzone-preview",
autoProcessQueue: false,
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
},
init: function () {
this.on("success", function (file, response) {
document.getElementById("toast-message").innerText =
response.message;
toast.show();
setTimeout(() => {
window.location.href = "/data/customers";
}, 2000);
});
this.on("error", function (file, errorMessage) {
document.getElementById("toast-message").innerText =
errorMessage.message;
toast.show();
this.uploadButton.disabled = false;
this.spinner.classList.add("d-none");
});
},
})));
}
setupUploadButton() {
this.uploadButton.addEventListener("click", (e) => {
if (this.spatialDropzone.files.length > 0) {
this.spatialDropzone.processQueue();
this.uploadButton.disabled = true;
this.spinner.classList.remove("d-none");
} else {
return;
}
});
}
}
document.addEventListener("DOMContentLoaded", function (e) {
new UploadCustomers().init();
});

View File

@@ -49,13 +49,31 @@ class BigData {
}
async updateData(year) {
try {
this.totalTargetPAD = await this.getTargetPAD(year);
this.totalTargetPAD = await this.getDataSettings("TARGET_PAD");
this.resultDataTotal = await this.getDataTotalPotensi(year);
this.dataVerification = await this.getDataVerfication(year);
this.dataNonVerification = await this.getDataNonVerfication(year);
this.dataBusiness = await this.getDataBusiness(year);
this.dataNonBusiness = await this.getDataNonBusiness(year);
this.dataTataRuang = await this.getDataTataRuang(year);
this.dataTataRuang = await this.getDataSettings("TATA_RUANG");
this.dataSumRealisasiTerbit = await this.getDataSettings(
"REALISASI_TERBIT_PBG_SUM"
);
this.dataCountRealisasiTerbit = await this.getDataSettings(
"REALISASI_TERBIT_PBG_COUNT"
);
this.dataSumMenungguKlikDPMPTSP = await this.getDataSettings(
"MENUNGGU_KLIK_DPMPTSP_SUM"
);
this.dataCountMenungguKlikDPMPTSP = await this.getDataSettings(
"MENUNGGU_KLIK_DPMPTSP_COUNT"
);
this.dataSumProsesDinasTeknis = await this.getDataSettings(
"PROSES_DINAS_TEKNIS_SUM"
);
this.dataCountProsesDinasTeknis = await this.getDataSettings(
"PROSES_DINAS_TEKNIS_COUNT"
);
// total potensi
this.bigTargetPAD = new Big(this.totalTargetPAD ?? 0);
@@ -100,7 +118,7 @@ class BigData {
this.dataNonVerification.total
);
this.percentageResultNonVerification =
this.bigTotalNonVerification <= 0 || this.bigTotalPotensi
this.bigTotalNonVerification <= 0 || this.bigTotalPotensi <= 0
? 0
: this.bigTotalNonVerification
.div(this.bigTotalPotensi)
@@ -120,7 +138,7 @@ class BigData {
// business documents
this.bigTotalBusiness = new Big(this.dataBusiness.total);
this.percentageResultBusiness =
this.bigTotalNonVerification <= 0
this.bigTotalNonVerification <= 0 || this.bigTotalBusiness <= 0
? 0
: this.bigTotalBusiness
.div(this.bigTotalNonVerification)
@@ -190,38 +208,6 @@ class BigData {
}
}
async getTargetPAD(year) {
try {
const response = await fetch(
`${GlobalConfig.apiHost}/api/api-data-settings?search=target_pad`,
{
credentials: "include",
headers: {
Authorization: `Bearer ${
document.querySelector("meta[name='api-token']")
.content
}`,
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
console.error("Network response was not ok", response);
return 0;
}
const data = await response.json();
const valueTargetPAD = data.data[0]?.value ?? 0;
const currentMonth = new Date().getMonth() + 1;
let result = (currentMonth / 12) * valueTargetPAD;
return result;
} catch (error) {
console.error("Error fetching chart data:", error);
return 0;
}
}
async getDataVerfication(year) {
try {
const response = await fetch(
@@ -346,10 +332,10 @@ class BigData {
}
}
async getDataTataRuang() {
async getDataSettings(string_key) {
try {
const response = await fetch(
`${GlobalConfig.apiHost}/api/api-data-settings?search=tata_ruang`,
`${GlobalConfig.apiHost}/api/api-data-settings?search=${string_key}`,
{
credentials: "include",
headers: {
@@ -519,12 +505,14 @@ class BigData {
document
.querySelectorAll(".document-count.chart-realisasi-tebit-pbg")
.forEach((element) => {
element.innerText = `0`;
element.innerText = `${this.dataCountRealisasiTerbit}`;
});
document
.querySelectorAll(".document-total.chart-realisasi-tebit-pbg")
.forEach((element) => {
element.innerText = `Rp.${addThousandSeparators("0.00")}`;
element.innerText = `Rp.${addThousandSeparators(
this.dataSumRealisasiTerbit
)}`;
});
document
.querySelectorAll(".small-percentage.chart-realisasi-tebit-pbg")
@@ -536,12 +524,14 @@ class BigData {
document
.querySelectorAll(".document-count.chart-menunggu-klik-dpmptsp")
.forEach((element) => {
element.innerText = `${0}`;
element.innerText = `${this.dataCountMenungguKlikDPMPTSP}`;
});
document
.querySelectorAll(".document-total.chart-menunggu-klik-dpmptsp")
.forEach((element) => {
element.innerText = `Rp.${addThousandSeparators("0.00")}`;
element.innerText = `Rp.${addThousandSeparators(
this.dataSumMenungguKlikDPMPTSP
)}`;
});
document
.querySelectorAll(".small-percentage.chart-menunggu-klik-dpmptsp")
@@ -553,12 +543,14 @@ class BigData {
document
.querySelectorAll(".document-count.chart-proses-dinas-teknis")
.forEach((element) => {
element.innerText = `${0}`;
element.innerText = `${this.dataCountProsesDinasTeknis}`;
});
document
.querySelectorAll(".document-total.chart-proses-dinas-teknis")
.forEach((element) => {
element.innerText = `Rp.${addThousandSeparators("0.00")}`;
element.innerText = `Rp.${addThousandSeparators(
this.dataSumProsesDinasTeknis
)}`;
});
document
.querySelectorAll(".small-percentage.chart-proses-dinas-teknis")

View File

@@ -0,0 +1,119 @@
import Big from "big.js";
import GlobalConfig, { addThousandSeparators } from "../global-config.js";
class LackOfPotential {
async init() {
this.bigTotalLackPotential = 0;
this.totalPotensi = await this.getDataTotalPotensi(2025);
this.totalTargetPAD = await this.getDataSettings("TARGET_PAD");
this.bigTargetPAD = new Big(this.totalTargetPAD ?? 0);
this.bigTotalPotensi = new Big(this.totalPotensi.totalData ?? 0);
this.bigTotalLackPotential = this.bigTargetPAD - this.bigTotalPotensi;
this.initChartKekuranganPotensi();
}
async getDataTotalPotensi(year) {
try {
const response = await fetch(
`${GlobalConfig.apiHost}/api/all-task-documents?year=${year}`,
{
credentials: "include",
headers: {
Authorization: `Bearer ${
document.querySelector("meta[name='api-token']")
.content
}`,
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
console.error("Network response was not ok", response);
}
const data = await response.json();
return {
countData: data.data.count,
totalData: data.data.total,
};
} catch (error) {
console.error("Error fetching chart data:", error);
return null;
}
}
async getDataSettings(string_key) {
try {
const response = await fetch(
`${GlobalConfig.apiHost}/api/api-data-settings?search=${string_key}`,
{
credentials: "include",
headers: {
Authorization: `Bearer ${
document.querySelector("meta[name='api-token']")
.content
}`,
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
console.error("Network response was not ok", response);
}
const data = await response.json();
return data.data[0].value;
} catch (error) {
console.error("Error fetching chart data:", error);
return 0;
}
}
initChartKekuranganPotensi() {
document
.querySelectorAll(".document-count.chart-lack-of-potential")
.forEach((element) => {
element.innerText = ``;
});
document
.querySelectorAll(".document-total.chart-lack-of-potential")
.forEach((element) => {
element.innerText = `Rp.${addThousandSeparators(
this.bigTotalLackPotential.toString()
)}`;
});
document
.querySelectorAll(".small-percentage.chart-lack-of-potential")
.forEach((element) => {
element.innerText = ``;
});
}
}
document.addEventListener("DOMContentLoaded", async function (e) {
await new LackOfPotential().init();
});
function resizeDashboard() {
let targetElement = document.getElementById("lack-of-potential-wrapper");
let dashboardElement = document.getElementById(
"lack-of-potential-fixed-container"
);
let targetWidth = targetElement.offsetWidth;
let dashboardWidth = 1400;
let scaleFactor = (targetWidth / dashboardWidth).toFixed(2);
// Prevent scaling beyond 1 (100%) to avoid overflow
scaleFactor = Math.min(scaleFactor, 1);
dashboardElement.style.transformOrigin = "left top";
dashboardElement.style.transition = "transform 0.2s ease-in-out";
dashboardElement.style.transform = `scale(${scaleFactor})`;
// Ensure horizontal scrolling is allowed if necessary
document.body.style.overflowX = "auto";
}
window.addEventListener("load", resizeDashboard);
window.addEventListener("resize", resizeDashboard);

View File

@@ -0,0 +1,470 @@
import Big from "big.js";
import GlobalConfig, { addThousandSeparators } from "../global-config.js";
import ApexCharts from "apexcharts";
import "gridjs/dist/gridjs.umd.js";
import GeneralTable from "../table-generator.js";
var chart;
document.addEventListener("DOMContentLoaded", async function () {
await initChart();
const yearPicker = document.getElementById("yearPicker");
async function updateDataByYear(selectedYear) {
// Target PAD Element
const targetPadElement = document.getElementById("target-pad");
if (!targetPadElement) return;
const targetPadValue = await getDataSettings("TARGET_PAD");
targetPadElement.textContent = formatCurrency(targetPadValue);
// Total Potensi Berkas
const totalPotensiBerkas = document.getElementById("total-potensi-berkas");
if (!totalPotensiBerkas) return;
const totalPotensiBerkasValue = await getDataTotalPotensi(selectedYear);
totalPotensiBerkas.textContent = formatCurrency(totalPotensiBerkasValue.totalData);
// Total Berkas Terverifikasi
const totalBerkasTerverifikasi = document.getElementById("total-berkas-terverifikasi");
if (!totalBerkasTerverifikasi) return;
const totalBerkasTerverifikasiValue = await getDataVerification(selectedYear);
totalBerkasTerverifikasi.textContent = formatCurrency(totalBerkasTerverifikasiValue.totalData);
// Total Kekurangan potensi
const totalKekuranganPotensi = document.getElementById("total-kekurangan-potensi");
if (!totalKekuranganPotensi) return;
const totalKekuranganPotensiValue = new Big(targetPadValue) - new Big(totalPotensiBerkasValue.totalData);
totalKekuranganPotensi.textContent = formatCurrency(totalKekuranganPotensiValue)
// Total Potensi PBG dari tata ruang
const totalPotensiPBGTataRuang = document.getElementById("total-potensi-pbd-tata-ruang");
if (!totalPotensiPBGTataRuang) return;
const totalPotensiPBGTataRuangValue = await getDataSettings("TATA_RUANG");
totalPotensiPBGTataRuang.textContent = formatCurrency(totalPotensiPBGTataRuangValue);
// Total Berkas Belum terverifikasi
const totalBerkasBelumTerverifikasi = document.getElementById("total-berkas-belum-terverifikasi");
if (!totalBerkasBelumTerverifikasi) return;
const totalBerkasBelumTerverifikasiValue = await getDataNonVerification(selectedYear);
const totalBerkasBelumTerverifikasiCount = totalBerkasBelumTerverifikasiValue.countData;
totalBerkasBelumTerverifikasi.textContent = formatCurrency(totalBerkasBelumTerverifikasiValue.totalData);
// Total Berkas Usaha
const totalBerkasUsahaValue = await getDataBusiness(selectedYear);
const totalBerkasUsahaCount = totalBerkasUsahaValue.countData;
const totalBerkasUsahaTotalData = totalBerkasUsahaValue.totalData;
// Total Berkas Non Usaha
const totalBerkasNonUsahaValue = await getDataNonBusiness(selectedYear);
const totalBerkasNonUsahaCount = totalBerkasNonUsahaValue.countData;
const totalBerkasNonUsahaTotalData = totalBerkasNonUsahaValue.totalData;
// Pie Chart Section
let persenUsaha = totalBerkasBelumTerverifikasiCount > 0
? ((totalBerkasUsahaCount / totalBerkasBelumTerverifikasiCount) * 100).toFixed(2)
: "0";
let persenNonUsaha = totalBerkasBelumTerverifikasiCount > 0
? ((totalBerkasNonUsahaCount / totalBerkasBelumTerverifikasiCount) * 100).toFixed(2)
: "0";
const dataSeriesPieChart = [Number(persenUsaha), Number(persenNonUsaha)]
const labelsPieChart = ["Berkas Usaha", "Berkas Non Usaha"];
document.querySelector("td[data-category='non-usaha']").textContent = formatCurrency(totalBerkasNonUsahaTotalData).toLocaleString();
document.querySelector("td[data-category='non-usaha-percentage']").textContent = persenNonUsaha + "%";
document.querySelector("td[data-category='usaha']").textContent = formatCurrency(totalBerkasUsahaTotalData).toLocaleString();
document.querySelector("td[data-category='usaha-percentage']").textContent = persenUsaha + "%";
updatePieChart(dataSeriesPieChart, labelsPieChart);
// Load all Tourism location
const allLocation = await getAllLocation();
console.log(allLocation);
// Filter hanya data yang memiliki angka valid
let validLocations = allLocation.dataLocation.filter(loc => {
return !isNaN(parseFloat(loc.longitude)) && !isNaN(parseFloat(loc.latitude));
});
// Ubah string ke float
validLocations = validLocations.map(loc => ({
name: loc.project_name,
longitude: parseFloat(loc.longitude),
latitude: parseFloat(loc.latitude)
}));
console.log(validLocations.name)
// Inisialisasi peta
var map = L.map('map').setView([-7.0230, 107.5275], 10);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; OpenStreetMap contributors'
}).addTo(map);
// Tambahkan marker ke peta
validLocations.forEach(function(loc) {
L.marker([loc.latitude, loc.longitude])
.addTo(map)
.bindPopup(`<b>${loc.name}</b>`) // Popup saat diklik
.bindTooltip(loc.name, { permanent: false, direction: "top" }); // Tooltip saat di-hover
});
// Realisasi terbit PBG
const totalRealisasiTerbitPBG = document.getElementById("realisasi-terbit-pbg");
if (!totalRealisasiTerbitPBG) return;
const totalRealisasiTerbitPBGValue = await getDataSettings("REALISASI_TERBIT_PBG_SUM");
totalRealisasiTerbitPBG.textContent = formatCurrency(totalRealisasiTerbitPBGValue);
// Menunggu Klik DPMPTSP
const totalMenungguKlikDpmptsp = document.getElementById("waiting-click-dpmptsp");
if (!totalMenungguKlikDpmptsp) return;
const totalMenungguKlikDpmptspValue = await getDataSettings("MENUNGGU_KLIK_DPMPTSP_SUM");
totalMenungguKlikDpmptsp.textContent = formatCurrency(totalMenungguKlikDpmptspValue);
// Proses Dinas Teknis
const totalProsesDinasTeknis = document.getElementById("processing-technical-services");
if (!totalProsesDinasTeknis) return;
const totalProsesDinasTeknisValue = await getDataSettings("PROSES_DINAS_TEKNIS_SUM");
totalProsesDinasTeknis.textContent = formatCurrency(totalProsesDinasTeknisValue);
// Load Tabel Baru di Update
const tableLastUpdated = new GeneralTable(
"pbg-filter-by-updated-at",
`${GlobalConfig.apiHost}/api/api-pbg-task?isLastUpdated=true`,
`${GlobalConfig.apiHost}`,
pbgTaskColumns
);
tableLastUpdated.processData = function (data) {
console.log("Response Data:", data);
return data.data.map((item) => {
return [
item.no,
item.name,
item.registration_number,
item.document_number,
item.address,
];
});
};
tableLastUpdated.init();
// Load Tabel Status SK Terbit
const tableSKPBGTerbit = new GeneralTable(
"pbg-filter-by-status",
`${GlobalConfig.apiHost}/api/api-pbg-task?isLastUpdated=false`,
`${GlobalConfig.apiHost}`,
pbgTaskColumns
);
tableSKPBGTerbit.processData = function (data) {
console.log("Response Data:", data);
return data.data.map((item) => {
return [
item.no,
item.name,
item.registration_number,
item.document_number,
item.address,
];
});
};
tableSKPBGTerbit.init();
document.querySelector("#pbg-filter-by-updated-at .gridjs-search").hidden = true;
document.querySelector("#pbg-filter-by-updated-at .gridjs-footer").hidden = true;
document.querySelector("#pbg-filter-by-status .gridjs-search").hidden = true;
document.querySelector("#pbg-filter-by-status .gridjs-footer").hidden = true;
}
await updateDataByYear(yearPicker.value);
yearPicker.addEventListener("change", async function () {
console.log("event change dropdown")
await updateDataByYear(yearPicker.value);
});
});
async function getDataSettings(string_key) {
try {
const response = await fetch(
`${GlobalConfig.apiHost}/api/api-data-settings?search=${string_key}`,
{
credentials: "include",
headers: {
Authorization: `Bearer ${
document.querySelector("meta[name='api-token']").content
}`,
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
console.error("Network response was not ok", response);
}
const data = await response.json();
return data.data?.[0]?.value ?? 0; // Pastikan tidak error jika data kosong
} catch (error) {
console.error("Error fetching data:", error);
return 0;
}
}
async function getDataTotalPotensi(year) {
try {
const response = await fetch(
`${GlobalConfig.apiHost}/api/all-task-documents?year=${year}`,
{
credentials: "include",
headers: {
Authorization: `Bearer ${
document.querySelector("meta[name='api-token']").content
}`,
"Content-Type": "application/json"
},
}
);
if (!response.ok) {
console.error("Network response was not ok", response);
}
const data = await response.json();
return {
totalData: data.data.total,
};
} catch (error) {
console.error("Error fetching chart data:", error);
return null;
}
}
async function getDataVerification(year) {
try {
const response = await fetch(
`${GlobalConfig.apiHost}/api/verification-documents?year=${year}`,
{
credentials: "include",
headers: {
Authorization: `Bearer ${
document.querySelector("meta[name='api-token']")
.content
}`,
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
console.error("Network response was not ok", response);
}
const data = await response.json()
return {
totalData: data.data.total,
};
} catch (error) {
console.error("Error fetching chart data:", error);
return 0
}
}
async function getDataNonVerification(year) {
try {
const response = await fetch (
`${GlobalConfig.apiHost}/api/non-verification-documents?year=${year}`,
{
credentials: "include",
headers: {
Authorization: `Bearer ${
document.querySelector("meta[name='api-token']")
.content
}`,
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
console.error("Network response was not ok", response);
}
const data = await response.json();
return {
countData: data.data.count,
totalData: data.data.total,
}
} catch (error) {
console.error("Error fetching chart data:", error);
return 0;
}
}
async function getDataBusiness(year) {
try {
const response = await fetch(
`${GlobalConfig.apiHost}/api/business-documents?year=${year}`,
{
credentials: "include",
headers: {
Authorization: `Bearer ${
document.querySelector("meta[name='api-token']")
.content
}`,
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
console.error("Network response was not ok", response);
}
const data = await response.json();
return {
countData: data.data.count,
totalData: data.data.total,
};
} catch (error) {
console.error("Error fetching chart data:", error);
return 0;
}
}
async function getDataNonBusiness(year) {
try {
const response = await fetch(
`${GlobalConfig.apiHost}/api/non-business-documents?year=${year}`,
{
credentials: "include",
headers: {
Authorization: `Bearer ${
document.querySelector("meta[name='api-token']")
.content
}`,
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
console.error("Network response was not ok", response);
}
const data = await response.json();
return {
countData: data.data.count,
totalData: data.data.total
}
} catch (error) {
console.error("Error fetching chart data:", error);
return 0;
}
}
async function getAllLocation() {
try {
const response = await fetch(
`${GlobalConfig.apiHost}/api/get-all-location`,
{
credentials: "include",
headers: {
Authorization: `Bearer ${
document.querySelector("meta[name='api-token']")
.content
}`,
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
console.error("Network response was not ok", response);
}
const data = await response.json();
return {
dataLocation: data.data,
}
} catch (error) {
console.error("Error fetching chart data:", error);
return 0;
}
}
async function initChart() {
var options = {
chart: {
height: 180,
type: 'donut',
},
series: [0, 0], // Inisialisasi dengan nilai awal
labels: ["Berkas Usaha", "Berkas Non Usaha"],
legend: {
show: false
},
stroke: {
width: 0
},
plotOptions: {
pie: {
donut: {
size: '60%',
}
}
},
colors: ["#7e67fe", "#17c553"],
dataLabels: {
enabled: false
},
responsive: [{
breakpoint: 480,
options: {
chart: {
width: 200
}
}
}],
fill: {
type: 'gradient'
}
};
chart = new ApexCharts(document.querySelector("#conversions"), options);
chart.render();
}
async function updatePieChart(dataSeries, labels) {
if (!Array.isArray(dataSeries) || dataSeries.length === 0) {
console.error("Data series tidak valid:", dataSeries);
return;
}
// Perbarui data series chart
chart.updateSeries(dataSeries);
// Perbarui label jika diperlukan
if (Array.isArray(labels) && labels.length === dataSeries.length) {
chart.updateOptions({
labels: labels
});
}
}
// Fungsi untuk format angka ke Rupiah
function formatCurrency(number) {
return new Intl.NumberFormat("id-ID", {
style: "currency",
currency: "IDR",
minimumFractionDigits: 0
}).format(number);
}
const pbgTaskColumns = [
"No",
"Name",
"Nomor Registrasi",
"Nomor Dokumen",
"Alamat",
]

View File

@@ -57,7 +57,7 @@ class DataSettings {
<a href="/data-settings/${cell}/edit" class="btn btn-yellow btn-sm d-inline-flex align-items-center justify-content-center">
<i class='bx bx-edit'></i>
</a>
<button class="btn btn-sm btn-red d-inline-flex align-items-center justify-content-centerbtn-delete-data-settings" data-id="${cell}">
<button class="btn btn-sm btn-red d-inline-flex align-items-center justify-content-center btn-delete-data-settings" data-id="${cell}">
<i class='bx bxs-trash' ></i>
</button>
</div>

View File

@@ -28,12 +28,7 @@ document.addEventListener("DOMContentLoaded", function () {
data[key] = value;
});
// Log semua data dalam FormData
for (let pair of formData.entries()) {
console.log(pair[0] + ": " + pair[1]);
}
const url = form.getAttribute("action");
console.log("Ini adalah url dari form action", url);
const method = isEdit ? "PUT" : "POST";
@@ -49,7 +44,6 @@ document.addEventListener("DOMContentLoaded", function () {
})
.then(response => response.json())
.then(data => {
console.log("Response data:", data);
if (!data.errors) {
// Remove existing icon (if any) before adding the new one
if (authLogo) {
@@ -74,11 +68,11 @@ document.addEventListener("DOMContentLoaded", function () {
toast.classList.add('show'); // Show the toast
setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000);
}, 2000);
setTimeout(() => {
window.location.href = '/data/advertisements';
}, 3000);
}, 1000);
} else {
if (authLogo) {
// Hapus ikon yang sudah ada jika ada
@@ -96,21 +90,21 @@ document.addEventListener("DOMContentLoaded", function () {
// Tambahkan ikon ke dalam auth-logo
authLogo.appendChild(icon);
}
// Set error message for the toast
toastBody.textContent = "Error: " + (responseData.message || "Something went wrong");
toast.classList.add('show'); // Show the toast
// Enable button and reset its text on error
modalButton.disabled = false;
modalButton.innerHTML = isEdit ? "Update" : "Create";
// Set error message for the toast
toastBody.textContent = "Failed: " + (data.message || "Something went wrong");
toast.classList.add('show'); // Show the toast
setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000);
}
})
.catch(error => {
console.error("Error:", error);
.catch(errors => {
if (authLogo) {
// Hapus ikon yang sudah ada jika ada
const existingIcon = authLogo.querySelector('.bx');
@@ -127,14 +121,14 @@ document.addEventListener("DOMContentLoaded", function () {
// Tambahkan ikon ke dalam auth-logo
authLogo.appendChild(icon);
}
// Enable button and reset its text on error
modalButton.disabled = false;
modalButton.innerHTML = isEdit ? "Update" : "Create";
// Set error message for the toast
toastBody.textContent = "An error occurred while processing your request.";
toast.classList.add('show'); // Show the toast
// Enable button and reset its text on error
modalButton.disabled = false;
modalButton.innerHTML = isEdit ? "Update" : "Create";
setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000);
@@ -144,7 +138,6 @@ document.addEventListener("DOMContentLoaded", function () {
// Fungsi fetchOptions untuk autocomplete server-side
window.fetchOptions = function (field) {
let inputValue = document.getElementById(field).value;
console.log("Query Value:", inputValue); // Debugging log
if (inputValue.length < 2) return;
let districtValue = document.getElementById("district_name").value; // Ambil kecamatan terpilih

View File

@@ -1,4 +1,5 @@
import { Dropzone } from "dropzone";
import GlobalConfig from "../../global-config.js";
Dropzone.autoDiscover = false;
@@ -14,7 +15,7 @@ console.log(dropzonePreviewNode);
((previewTemplate = dropzonePreviewNode.parentNode.innerHTML),
dropzonePreviewNode.parentNode.removeChild(dropzonePreviewNode),
(dropzone = new Dropzone(".dropzone", {
url: "http://localhost:8000/api/advertisements/import",
url: `${GlobalConfig.apiHost}/api/advertisements/import`,
// url: "https://httpbin.org/post",
method: "post",
acceptedFiles: ".xls,.xlsx", // Use acceptedFiles for better validation
@@ -85,6 +86,40 @@ dropzone.on("complete", function(file) {
dropzone.removeFile(file);
});
// Add event listener to donwload file template
document.getElementById('downloadtempadvertisement').addEventListener('click', function() {
var url = `${GlobalConfig.apiHost}/api/download-template-advertisement`;
fetch(url, {
method: 'GET',
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`
},
})
.then(response => {
if (response.ok) {
return response.blob();
} else {
return response.json();
}
})
.then((blob) => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'template_reklame.xlsx';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
})
.catch((error) => {
console.error("Gagal mendownload file:", error);
showToast('bxs-error-alt', 'red', "Template file is not already exist.");
})
})
// Function to show toast
function showToast(iconClass, iconColor, message) {
const toastElement = document.getElementById('toastUploadAdvertisement');

Some files were not shown because too many files have changed in this diff Show More