Compare commits

..

9 Commits

Author SHA1 Message Date
@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
@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
@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
47 changed files with 1980 additions and 211 deletions

View File

@@ -199,7 +199,7 @@ class AdvertisementController extends Controller
public function downloadExcelAdvertisement()
{
$filePath = storage_path('app/public/templates/template_reklame.xlsx');
$filePath = public_path('templates/template_reklame.xlsx');
// Cek apakah file ada
if (!file_exists($filePath)) {

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

@@ -21,32 +21,41 @@ class TourismController extends Controller
*/
public function index(Request $request)
{
info($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 = $district ? $district->district_name : null;
$business_type = DB::table('business_type')->where('id', $tourisms->business_type_id)->first();
$tourisms->business_type = $business_type ? $business_type->business_type : 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' => TourismResource::collection($tourisms),
'data' => $data,
'meta' => [
'total' => $tourisms->total(),
'per_page' => $tourisms->perPage(),
'current_page' => $tourisms->currentPage(),
'last_page' => $tourisms->lastPage(),
'last_page'=>$tourisms->lastPage(),
]
]);
}
@@ -62,11 +71,12 @@ class TourismController extends Controller
$data['district_code'] = $district_code;
$data['village_code'] = $village_code;
return Tourism::create($data);
}
/**
* Import advertisements from Excel or CSV
* Import advertisements from Excel
*/
public function importFromFile(Request $request)
{
@@ -77,21 +87,21 @@ class TourismController extends Controller
if ($validator->fails()) {
return response()->json([
'message' => 'File validation failed.',
'errors' => $validator->errors()
'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!'
'message'=>'File uploaded and imported successfully!'
], 200);
} catch (\Exception $e) {
return response()->json([
'message' => 'Error during file import.',
'error' => $e->getMessage()
'message'=>'Error during file import.',
'error'=>$e->getMessage()
], 500);
}
}
@@ -109,7 +119,17 @@ class TourismController extends Controller
*/
public function update(TourismRequest $request, Tourism $tourism): Tourism
{
$tourism->update($request->validated());
$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;
}
@@ -120,4 +140,18 @@ class TourismController extends Controller
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

@@ -27,6 +27,17 @@ class UmkmController extends Controller
$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) {
@@ -47,8 +58,14 @@ class UmkmController extends Controller
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' => UmkmResource::collection($umkm),
'data' => $data,
'meta' => [
'total' => $umkm->total(),
'per_page' => $umkm->perPage(),
@@ -69,9 +86,9 @@ class UmkmController extends Controller
// 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'])->value('id');
$permit_status_id = DB::table('permit_status')->where('id', $data['permit_status'])->value('id');
$business_form_id = DB::table('business_form')->where('id', $data['business_form'])->value('id');
$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);
@@ -176,7 +193,7 @@ class UmkmController extends Controller
public function downloadExcelUmkm()
{
$filePath = storage_path('app/public/templates/template_umkm.xlsx');
$filePath = public_path('templates/template_umkm.xlsx');
// Cek apakah file ada
if (!file_exists($filePath)) {

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

@@ -36,9 +36,7 @@ class TourismController extends Controller
// 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_type_id' => DB::table('business_type')->orderBy('business_type')->pluck('business_type', 'id'),
'business_scale_id' => DB::table('business_scale')->orderBy('business_scale')->pluck('business_scale', 'id'),
'district_name' => DB::table('districts')->orderBy('district_name')->pluck('district_name', 'district_code')
];
$fields = $this->getFields();
@@ -55,7 +53,7 @@ class TourismController extends Controller
public function edit($id)
{
$title = 'Pariwisata';
$subtitle = 'Create Data';
$subtitle = 'Update Data';
$modelInstance = Tourism::find($id);
// Pastikan model ditemukan
@@ -70,13 +68,9 @@ class TourismController extends Controller
$district = DB::table('districts')->where('district_code', $modelInstance->district_code)->first();
$modelInstance->district_name = $district ? $district->district_name : null;
$business_type = DB::table('business_type')->where('id', $modelInstance->business_type_id)->first();
$modelInstance->business_scale_id = $business_type ? $business_type->id : 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'),
'business_type_id' => DB::table('business_type')->orderBy('business_type')->pluck('business_type', 'id'),
'district_name' => DB::table('districts')->orderBy('district_name')->pluck('district_name', 'district_code')
];
$fields = $this->getFields();
@@ -90,46 +84,62 @@ class TourismController extends Controller
private function getFields()
{
return [
"business_name" => "Nama Usaha",
"business_form" => "Bentuk Usaha",
"project_name" => "Nama Project",
"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",
"land_area" => "Luas Tanah",
"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",
"number_of_employee" => "TKI",
"business_type_id" => "Jenis Usaha",
"project_id" => "Priject ID",
"nib" => "NIB",
"jenis_proyek" => "Jenis Proyek",
"status_penanaman_modal" => "Status Penanaman Modal",
"uraian_resiko_proyek" => "Uraian Resiko Proyek",
"business_scale_id" => "Skala Bisnis/Usaha",
"terbit_oss" => "Terbit OSS",
"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_address" => "textarea",
"business_scale" => "text",
"business_address" => "text",
"district_name" => "combobox",
"village_name" => "combobox",
"land_area" => "text",
"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",
"number_of_employee" => "text",
"business_type_id" => "select",
"project_id" => "text",
"nib" => "text",
"jenis_proyek" => "text",
"status_penanaman_modal" => "text",
"uraian_resiko_proyek" => "text",
"business_scale_id" => "select",
"terbit_oss" => "date"
"tki" => "text",
];
}
}

View File

@@ -3,7 +3,7 @@
namespace App\Http\Controllers\Report;
use App\Http\Controllers\Controller;
use App\Models\BusinessTypeCount;
use App\Models\TourismBasedKBLI;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@@ -14,8 +14,8 @@ class ReportTourismController extends Controller
*/
public function index()
{
$businessTypeCounts = BusinessTypeCount::all();
info($businessTypeCounts);
return view('report.tourisms.index', compact('businessTypeCounts'));
$tourismBasedKBLI = TourismBasedKBLI::all();
info($tourismBasedKBLI);
return view('report.tourisms.index', compact('tourismBasedKBLI'));
}
}

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,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

@@ -22,23 +22,112 @@ class TourismRequest extends FormRequest
public function rules(): array
{
return [
'jenis_proyek' => 'required|string',
'nib' => 'string',
'business_name' => 'required|string',
'status_penanaman_modal' => 'string',
'business_form' => 'string',
'uraian_resiko_proyek' => 'string',
'project_name' => 'required|string',
'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|string',
'village_name' => 'required|string',
'land_area' => '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',
'number_of_employee' => 'required|string',
'business_type_id' => 'required|string',
'terbit_oss' => 'required|date',
'business_scale_id' => 'required',
'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

@@ -65,7 +65,7 @@ class UmkmRequest extends FormRequest
'business_id_number.string' => 'Nomor ID usaha harus berupa teks.',
'business_scale.required' => 'Skala usaha wajib diisi.',
'business_scale_id.required' => 'Skala usaha wajib diisi.',
'owner_id.required' => 'ID pemilik wajib diisi.',
'owner_id.string' => 'ID pemilik harus berupa teks.',
@@ -96,7 +96,7 @@ class UmkmRequest extends FormRequest
'number_of_employee.required' => 'Jumlah karyawan wajib diisi.',
'permit_status.required' => 'Status izin 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.',

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,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

@@ -7,6 +7,7 @@ use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Illuminate\Support\Facades\DB;
use DateTime;
use Carbon\Carbon;
class TourismImport implements ToCollection
{
@@ -41,13 +42,11 @@ class TourismImport implements ToCollection
if ($headerIndex === false) {
return;
}
info($rows);
foreach ($rows->skip(1) as $row) {
// Normalisasi nama kecamatan dan desa
$districtName = strtolower(trim(str_replace('Kecamatan', '', $row[13])));
$villageName = strtolower(trim($row[14]));
$districtName = strtolower(trim(str_replace('Kecamatan', '', $row[12])));
$villageName = strtolower(trim($row[13]));
// Cari distric_code dari table districts
$districtCode = $districts[$districtName] ?? null;
@@ -66,24 +65,42 @@ class TourismImport implements ToCollection
// 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],
'jenis_proyek' => $row[2],
'project_type_id' => $row[2],
'nib' => $row[3],
'business_name' => $row[4],
'terbit_oss' => DateTime::createFromFormat('d/m/Y', $row[5])->format('Y-m-d'),
'status_penanaman_modal' => $row[6],
'oss_publication_date' => DateTime::createFromFormat('d/m/Y', $row[5]),
'investment_status_description' => $row[6],
'business_form' => $row[7],
'uraian_resiko_proyek' => $row[8],
'project_risk' => $row[8],
'project_name' => $row[9],
'business_type_id' => $row[10],
'business_scale_id' => (int) $row[11],
'business_scale' => $row[10],
'business_address' => $row[12],
'district_code' => $districtCode,
'village_code' => $villageCode,
'land_area' => $row[15],
'investment_amount' => (string) $row[16],
'number_of_employee' => (string) $row[17],
'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]
];
}

View File

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

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'];
}

View File

@@ -8,25 +8,33 @@ use Illuminate\Database\Eloquent\Model;
* Class Tourism
*
* @property $id
* @property $project_id
* @property $jenis_proyek
* @property $nib
* @property $created_at
* @property $updated_at
* @property $project_id
* @property $project_type_id
* @property $nib
* @property $business_name
* @property $terbit_oss
* @property $status_penanaman_modal
* @property $oss_publication_date
* @property $investment_status_description
* @property $business_form
* @property $uraian_resiko_proyek
* @property $project_risk
* @property $project_name
* @property $business_scale_id
* @property $business_scale
* @property $business_address
* @property $district_code
* @property $village_code
* @property $land_area
* @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 $number_of_employee
* @property $business_type_id
* @property $tki
*
* @package App
* @mixin \Illuminate\Database\Eloquent\Builder
@@ -41,7 +49,7 @@ class Tourism extends Model
*
* @var array<int, string>
*/
protected $fillable = ['project_id', 'jenis_proyek', 'nib', 'business_name', 'terbit_oss', 'status_penanaman_modal', 'business_form', 'uraian_resiko_proyek', 'project_name', 'business_scale_id', 'business_address', 'district_code', 'village_code', 'land_area', 'investment_amount', 'number_of_employee', 'business_type_id'];
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'];
}

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

@@ -136,7 +136,7 @@
"isEntry": true
},
"resources/js/dashboards/bigdata.js": {
"file": "assets/bigdata-Cyb9tZIY.js",
"file": "assets/bigdata-BGlke4DN.js",
"name": "bigdata",
"src": "resources/js/dashboards/bigdata.js",
"isEntry": true,
@@ -421,6 +421,16 @@
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/report/tourisms/index.js": {
"file": "assets/index-DlxOSPEG.js",
"name": "index",
"src": "resources/js/report/tourisms/index.js",
"isEntry": true,
"imports": [
"_gridjs.umd-BiCNXlqL.js",
"__commonjsHelpers-C4iS2aBk.js"
]
},
"resources/js/roles/create.js": {
"file": "assets/create-Dd-lHOwF.js",
"name": "create",
@@ -499,7 +509,7 @@
"isEntry": true
},
"resources/scss/style.scss": {
"file": "assets/style-C8C4w8xF.css",
"file": "assets/style-CnBzxVPJ.css",
"src": "resources/scss/style.scss",
"isEntry": true
}

Binary file not shown.

Binary file not shown.

View File

@@ -138,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)

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

@@ -0,0 +1,63 @@
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";
import GeneralTable from "../../table-generator.js";
const dataSpatialPlanningColumns = [
"No",
"Nama",
"KBLI",
"Kegiatan",
"Luas",
"Lokasi",
"Nomor",
"Tanggal",
{
name: "Actions",
widht: "120px",
formatter: function (cell, row) {
const id = row.cells[8].data;
const model = "data/spatial-plannings";
return gridjs.html(`
<div class="d-flex justify-items-end gap-10">
<button class="btn btn-warning me-2 btn-edit"
data-id="${id}"
data-model="${model}">
<i class='bx bx-edit'></i></button>
<button class="btn btn-red btn-delete"
data-id="${id}">
<i class='bx bxs-trash'></i></button>
</div>
`);
},
},
];
document.addEventListener("DOMContentLoaded", () => {
const table = new GeneralTable(
"spatial-planning-data-table",
`${GlobalConfig.apiHost}/api/spatial-plannings`,
`${GlobalConfig.apiHost}`,
dataSpatialPlanningColumns
);
table.processData = function (data) {
return data.data.map((item) => {
return [
item.no,
item.name,
item.kbli,
item.activities,
item.area,
item.location,
item.number,
item.date,
item.id,
];
});
};
table.init();
});

View File

@@ -0,0 +1,185 @@
import GlobalConfig from "../../global-config";
document.addEventListener("DOMContentLoaded", function () {
const saveButton = document.querySelector(".modal-footer .btn-primary");
const modalButton = document.querySelector(".btn-modal");
const form = document.querySelector("form#create-update-form");
var authLogo = document.querySelector(".auth-logo");
if (!saveButton || !form) return;
saveButton.addEventListener("click", function () {
// Disable tombol dan tampilkan spinner
modalButton.disabled = true;
modalButton.innerHTML = `
<span class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"></span>
Loading...
`;
const isEdit = saveButton.classList.contains("btn-edit");
const formData = new FormData(form);
const toast = document.getElementById("toastEditUpdate");
const toastBody = toast.querySelector(".toast-body");
const toastHeader = toast.querySelector(".toast-header small");
const data = {};
// Mengonversi FormData ke dalam JSON
formData.forEach((value, key) => {
data[key] = value;
});
const url = form.getAttribute("action");
const method = isEdit ? "PUT" : "POST";
fetch(url, {
method: method,
body: JSON.stringify(data),
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
})
.then((response) => response.json())
.then((data) => {
if (!data.errors) {
// Remove existing icon (if any) before adding the new one
if (authLogo) {
// Hapus ikon yang sudah ada jika ada
const existingIcon = authLogo.querySelector(".bx");
if (existingIcon) {
authLogo.removeChild(existingIcon);
}
// Buat ikon baru
const icon = document.createElement("i");
icon.classList.add("bx", "bxs-check-square");
icon.style.fontSize = "25px";
icon.style.color = "green"; // Pastikan 'green' dalam bentuk string
// Tambahkan ikon ke dalam auth-logo
authLogo.appendChild(icon);
}
// Set success message for the toast
toastBody.textContent = isEdit
? "Data updated successfully!"
: "Data created successfully!";
toast.classList.add("show"); // Show the toast
setTimeout(() => {
toast.classList.remove("show"); // Hide the toast after 3 seconds
}, 3000);
setTimeout(() => {
window.location.href = "/data/spatial-plannings";
}, 3000);
} else {
if (authLogo) {
// Hapus ikon yang sudah ada jika ada
const existingIcon = authLogo.querySelector(".bx");
if (existingIcon) {
authLogo.removeChild(existingIcon);
}
// Buat ikon baru
const icon = document.createElement("i");
icon.classList.add("bx", "bxs-error-alt");
icon.style.fontSize = "25px";
icon.style.color = "red"; // Pastikan 'green' dalam bentuk string
// Tambahkan ikon ke dalam auth-logo
authLogo.appendChild(icon);
}
// Set error message for the toast
toastBody.textContent =
"Error: " + (data.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";
setTimeout(() => {
toast.classList.remove("show"); // Hide the toast after 3 seconds
}, 3000);
}
})
.catch((error) => {
if (authLogo) {
// Hapus ikon yang sudah ada jika ada
const existingIcon = authLogo.querySelector(".bx");
if (existingIcon) {
authLogo.removeChild(existingIcon);
}
// Buat ikon baru
const icon = document.createElement("i");
icon.classList.add("bx", "bxs-error-alt");
icon.style.fontSize = "25px";
icon.style.color = "red"; // Pastikan 'green' dalam bentuk string
// Tambahkan ikon ke dalam auth-logo
authLogo.appendChild(icon);
}
// 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);
});
});
// Fungsi fetchOptions untuk autocomplete server-side
window.fetchOptions = function (field) {
let inputValue = document.getElementById(field).value;
if (inputValue.length < 2) return;
let districtValue = document.getElementById("district_name").value; // Ambil kecamatan terpilih
let url = `${
GlobalConfig.apiHost
}/api/combobox/search-options?query=${encodeURIComponent(
inputValue
)}&field=${field}`;
// Jika field desa, tambahkan kecamatan sebagai filter
if (field === "village_name") {
url += `&district=${encodeURIComponent(districtValue)}`;
}
fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
})
.then((response) => response.json())
.then((data) => {
let dataList = document.getElementById(field + "Options");
dataList.innerHTML = "";
data.forEach((item) => {
let option = document.createElement("option");
option.value = item.name;
option.dataset.code = item.code;
dataList.appendChild(option);
});
})
.catch((error) => console.error("Error fetching options:", error));
};
document.querySelector(".btn-back").addEventListener("click", function () {
window.history.back();
});
});

View File

@@ -0,0 +1,150 @@
import { Dropzone } from "dropzone";
import GlobalConfig from "../../global-config.js";
Dropzone.autoDiscover = false;
var previewTemplate,
dropzone,
dropzonePreviewNode = document.querySelector("#dropzone-preview-list");
console.log(previewTemplate);
console.log(dropzone);
console.log(dropzonePreviewNode);
(dropzonePreviewNode.id = ""),
dropzonePreviewNode &&
((previewTemplate = dropzonePreviewNode.parentNode.innerHTML),
dropzonePreviewNode.parentNode.removeChild(dropzonePreviewNode),
(dropzone = new Dropzone(".dropzone", {
url: `${GlobalConfig.apiHost}/api/spatial-plannings/import`,
// url: "https://httpbin.org/post",
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
showToast('bxs-check-square', 'green', response.message);
document.getElementById("submit-upload").innerHTML = "Upload Files";
// Tunggu sebentar lalu reload halaman
setTimeout(() => {
window.location.href = "/data/spatial-plannings";
}, 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
showToast('bxs-error-alt', 'red', errorMessage.message);
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
showToast('bxs-error-alt', 'red', "Please add a file first.");
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);
});
// Add event listener to download file template
document.getElementById('downloadtempspatialPlannings').addEventListener('click', function() {
var url = `${GlobalConfig.apiHost}/api/download-template-spatialPlannings`;
fetch(url, {
method: 'GET',
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`
},
})
.then(response => {
if (response.ok) {
return response.blob(); // Jika respons OK, konversi menjadi blob
} else {
return response.json(); // Jika respons gagal, konversi menjadi JSON untuk menangani pesan error
}
})
.then((blob) => {
console.log(blob);
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'template_rencana_tata_ruang.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('toastUploadSpatialPlannings');
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

@@ -5,37 +5,39 @@ import GlobalConfig from "../../global-config.js";
import GeneralTable from "../../table-generator.js";
const dataTourismsColumns = [
"Proyek ID",
"Jenis Proyek",
"NIB",
"No",
"Nama Perusahaan",
"Terbit OSS",
"Status Penanaman Modal",
"Bentuk Bisnis",
"Uraian Resiko Proyek",
"Nama Proyek",
"Alamat Usaha",
"Kecamatan",
"Desa",
"Luas Tanah",
"Luas Tanah (m2)",
"Jumlah Investasi",
"TKI",
"Tipe Usaha",
"Longitude",
"Latitude",
{
name: "Actions",
widht: "120px",
formatter: function (cell, row) {
const id = row.cells[16].data;
const id = row.cells[10].data;
const long = row.cells[8].data;
const lat = row.cells[9].data;
const model = "data/tourisms";
return gridjs.html(`
<div class="d-flex justify-items-end gap-10">
<button class="btn btn-warning me-2 btn-edit"
data-id="${id}"
data-model="${model}">
<i class='bx bx-edit' ></i></button>
<i class='bx bx-edit'></i></button>
<button class="btn btn-info me-2 btn-view"
data-long="${long}" data-lat="${lat}">
<i class='bx bx-map'></i></button>
<button class="btn btn-red btn-delete"
data-id="${id}">
<i class='bx bxs-trash' ></i></button>
data-id="${id}">
<i class='bx bxs-trash'></i></button>
</div>
`);
},
@@ -53,26 +55,43 @@ document.addEventListener("DOMContentLoaded", () => {
table.processData = function (data) {
return data.data.map((item) => {
return [
item.project_id,
item.jenis_proyek,
item.nib,
item.no,
item.business_name,
item.terbit_oss,
item.status_penanaman_modal,
item.business_form,
item.uraian_resiko_proyek,
item.project_name,
item.business_address,
item.district_name,
item.village_name,
item.land_area,
item.land_area_in_m2,
item.investment_amount,
item.number_of_employee,
item.business_type,
item.tki,
item.longitude,
item.latitude,
item.id,
];
});
};
table.init();
// Event listener untuk tombol "View" yang memunculkan modal
document.addEventListener("click", function (e) {
if (e.target && e.target.classList.contains("btn-view")) {
const long = e.target.getAttribute("data-long");
const lat = e.target.getAttribute("data-lat");
// Menyiapkan URL iframe dengan koordinat yang didapatkan
const iframeSrc = `https://www.google.com/maps?q=${lat},${long}&hl=es;z=14&output=embed`;
// Menemukan modal dan iframe di dalam modal
const modal = document.querySelector(".modalGMaps");
const iframe = modal.querySelector("iframe");
// Set src iframe untuk menampilkan peta dengan koordinat yang relevan
iframe.src = iframeSrc;
// Menampilkan modal
var modalInstance = new bootstrap.Modal(modal);
modalInstance.show();
}
});
});

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) {
@@ -113,7 +107,6 @@ document.addEventListener("DOMContentLoaded", function () {
}
})
.catch((error) => {
console.error("Error:", error);
if (authLogo) {
// Hapus ikon yang sudah ada jika ada
const existingIcon = authLogo.querySelector(".bx");
@@ -148,7 +141,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

@@ -88,7 +88,7 @@ dropzone.on("complete", function(file) {
// Add event listener to download file template
document.getElementById('downloadtemptourisms').addEventListener('click', function() {
var url = `${GlobalConfig.apiHost}/api/download-template-umkm`;
var url = `${GlobalConfig.apiHost}/api/download-template-tourism`;
fetch(url, {
method: 'GET',
headers: {
@@ -105,11 +105,12 @@ document.getElementById('downloadtemptourisms').addEventListener('click', functi
}
})
.then((blob) => {
console.log(blob);
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'template_tourisms.xlsx';
a.download = 'template_pariwisata.xlsx';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
@@ -122,7 +123,7 @@ document.getElementById('downloadtemptourisms').addEventListener('click', functi
// Function to show toast
function showToast(iconClass, iconColor, message) {
const toastElement = document.getElementById('toastUploadUmkm');
const toastElement = document.getElementById('toastUploadTourisms');
const toastBody = toastElement.querySelector('.toast-body');
const toastHeader = toastElement.querySelector('.toast-header');

View File

@@ -4,6 +4,7 @@ import GlobalConfig from "../../global-config.js";
import GeneralTable from "../../table-generator.js";
const dataUMKMColumns = [
"No",
"Nama Usaha",
"Alamat Usaha",
"Deskripsi Usaha",
@@ -54,6 +55,7 @@ document.addEventListener("DOMContentLoaded", () => {
table.processData = function (data) {
return data.data.map((item) => {
return [
item.no,
item.business_name,
item.business_address,
item.business_desc,

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";
@@ -74,11 +69,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/umkm';
}, 3000);
}, 1000);
} else {
if (authLogo) {
// Hapus ikon yang sudah ada jika ada
@@ -96,14 +91,16 @@ document.addEventListener("DOMContentLoaded", function () {
// Tambahkan ikon ke dalam auth-logo
authLogo.appendChild(icon);
}
// Set error message for the toast
toastBody.textContent = "Error: " + (data.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 = "Error: " + (data.message || "Something went wrong");
toast.classList.add('show'); // Show the toast
setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000);
@@ -127,14 +124,15 @@ document.addEventListener("DOMContentLoaded", function () {
// Tambahkan ikon ke dalam auth-logo
authLogo.appendChild(icon);
}
// 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";
// Set error message for the toast
toastBody.textContent = "An error occurred while processing your request.";
toast.classList.add('show'); // Show the toast
setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000);
@@ -144,7 +142,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

@@ -2,14 +2,14 @@ import gridjs from "gridjs/dist/gridjs.umd.js";
import "gridjs/dist/gridjs.umd.js";
// Mengambil data dari input dengan id="business_type_counts"
const businessTypeCountsElement = document.getElementById("business_type_counts");
const businessTypeCountsElement = document.getElementById("tourism_based_KBLI");
console.log(businessTypeCountsElement);
const businessTypeCounts = JSON.parse(businessTypeCountsElement.value); // Cek apakah data sudah terbawa dengan benar
// Membuat Grid.js instance
new gridjs.Grid({
columns: ["Jenis Bisnis Pariwisata", "Jumlah Total"], // Nama kolom
data: businessTypeCounts.map(item => [item.business_type, item.count]), // Mengubah data untuk Grid.js
data: businessTypeCounts.map(item => [item.kbli_title, item.total_records]), // Mengubah data untuk Grid.js
search: true, // Menambahkan fitur pencarian
pagination: true, // Menambahkan fitur pagination
sort: true, // Menambahkan fitur sorting

View File

@@ -0,0 +1,91 @@
@extends('layouts.vertical', ['subtitle' => 'File Upload'])
@section('content')
@include('layouts.partials/page-title', ['title' => 'Form', 'subtitle' => 'File Uploads'])
<div class="row">
<div class="col-xl-12">
<div class="card">
<div class="card-header">
<div class="d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">Upload Data Pariwisata</h5>
<button id="downloadtempspatialPlannings" class="btn btn-secondary">Download Template</button>
</div>
</div>
<div class="card-body">
<div class="mb-3">
<div class="dropzone">
<form action="" method="post" enctype="multipart/form-data">
<div class="fallback">
<input id="file-dropzone"type="file" name="file" multiple/>
</div>
</form>
<div class="dz-message needsclick">
<i class="h1 bx bx-cloud-upload"></i>
<h3>Drop files here or click to upload.</h3>
<p class="card-subtitle">
Please upload a file with the extension <strong>.xls or .xlsx</strong> with a maximum size of <strong>10 MB</strong>.
<br>
</p>
</div>
</div>
<ul class="list-unstyled mb-0" id="dropzone-preview">
<li class="mt-2" id="dropzone-preview-list">
<!-- This is used as the file preview template -->
<div class="border rounded">
<div class="d-flex align-items-center p-2">
<div class="flex-shrink-0 me-3">
<div class="avatar-sm bg-light rounded">
<img data-dz-thumbnail class="img-fluid rounded d-block" src="#"
alt="" />
</div>
</div>
<div class="flex-grow-1">
<div class="pt-1">
<h5 class="fs-14 mb-1" data-dz-name>&nbsp;
</h5>
<p class="fs-13 text-muted mb-0" data-dz-size></p>
<strong class="error text-danger" data-dz-errormessage></strong>
</div>
</div>
<div class="flex-shrink-0 ms-3">
<button data-dz-remove class="btn btn-sm btn-danger">Delete</button>
</div>
</div>
</div>
</li>
</ul>
<!-- end dropzon-preview -->
</div>
<div class="d-flex justify-content-end">
<button id="submit-upload" class="btn btn-primary">Upload Files</button>
</div>
</div> <!-- end card body -->
</div> <!-- end card -->
</div> <!-- end col -->
</div> <!-- end row -->
<div class="toast-container position-fixed end-0 top-0 p-3">
<div id="toastUploadSpatialPlannings" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<div class="auth-logo me-auto">
</div>
<small class="text-muted"></small>
<button type="button" class="btn-close" data-bs-dismiss="toast"
aria-label="Close"></button>
</div>
<div class="toast-body">
</div>
</div>
</div>
@endsection
@section('scripts')
@vite(['resources/js/data/spatialPlannings/form-upload.js'])
@endsection

View File

@@ -0,0 +1,130 @@
@extends('layouts.vertical', ['subtitle' => $subtitle]) <!-- Menggunakan subtitle dari controller -->
@section('content')
@include('layouts.partials/page-title', ['title' => $title, 'subtitle' => $subtitle]) <!-- Menggunakan title dan subtitle dari controller -->
<div class="row d-flex justify-content-center">
@if (session('error'))
<div class="alert alert-danger">
{{ session('error') }}
</div>
@endif
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="col-lg-12 col-md-12">
<div class="card">
<div class="card-header">
<button class="btn btn-danger float-end btn-back">
<i class='bx bx-arrow-back'></i>
Back
</button>
</div>
<div class="card-body">
<form id="create-update-form" action="{{ isset($modelInstance) && $modelInstance->id ? $apiUrl . '/' . $modelInstance->id : $apiUrl }}" method="POST">
@csrf
@if(isset($modelInstance))
@method('PUT')
@endif
<div class="row">
@foreach($fields as $field => $label)
<div class="col-md-6 form-group mb-3">
<label for="{{ $field }}">{{ $label }}</label>
@php
$fieldType = $fieldTypes[$field] ?? 'text'; // Default text jika tidak ditemukan tipe
@endphp
@if($fieldType == 'textarea')
<textarea id="{{ $field }}" name="{{ $field }}" class="form-control">{{ old($field, isset($modelInstance) ? $modelInstance->{$field} : '') }}</textarea>
@elseif($fieldType == 'select' && isset($dropdownOptions[$field]))
<select id="{{ $field }}" name="{{ $field }}" class="form-control">
@foreach($dropdownOptions[$field] as $code => $name)
@php
// $selectedValue = old($field, $modelInstance->{$field});
$selectedValue = old($field, $modelInstance->$field ?? '');
$isSelected = strval($selectedValue) === strval($code);
@endphp
<option value="{{ $code }}" class="{{ $isSelected ? 'selected' : '' }}" {{ $isSelected ? 'selected' : '' }}>
{{ $name }}
</option>
@endforeach
</select>
@elseif($fieldType == 'combobox' && isset($dropdownOptions[$field]))
<input class="form-control" list="{{ $field }}Options" id="{{ $field }}" name="{{ $field }}"
value="{{ old($field, isset($modelInstance) ? $modelInstance->{$field} : '') }}" placeholder="Type to search..." oninput="fetchOptions('{{ $field }}')">
<datalist id="{{ $field }}Options"></datalist>
@elseif($fieldType == 'date')
<input type="date" id="{{ $field }}" name="{{ $field }}" class="form-control"
value="{{ old($field, isset($modelInstance) && $modelInstance->{$field} ? \Carbon\Carbon::parse($modelInstance->{$field})->format('Y-m-d') : '') }}">
@else
<input type="{{ $fieldType }}" id="{{ $field }}" name="{{ $field }}" class="form-control" value="{{ old($field, isset($modelInstance) ? $modelInstance->{$field} : '') }}">
@endif
</div>
@endforeach
</div>
<div class="d-flex justify-content-end">
<button type="button" class="btn {{ isset($modelInstance) ? 'btn-warning' : 'btn-success' }} width-lg btn-modal" data-bs-toggle="modal" data-bs-target="#confirmationModalCenter">
{{ isset($modelInstance) ? 'Update' : 'Create' }}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="confirmationModalCenter" tabindex="-1"
aria-labelledby="confirmationModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirmationModalCenterTitle">
{{ isset($modelInstance) ? 'Update Confirmation' : 'Create Confirmation' }}
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<p>{{ isset($modelInstance) ? 'Are you sure you want to save the data changes?' : 'Are you sure you want to create new data based on the form contents?' }}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary {{ isset($modelInstance) ? 'btn-edit' : 'btn-create' }}" data-bs-dismiss="modal">Save changes</button>
</div>
</div>
</div>
</div>
<div class="toast-container position-fixed end-0 top-0 p-3">
<div id="toastEditUpdate" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<div class="auth-logo me-auto">
</div>
<small class="text-muted"></small>
<button type="button" class="btn-close" data-bs-dismiss="toast"
aria-label="Close"></button>
</div>
<div class="toast-body">
</div>
</div>
</div>
@endsection
@section('scripts')
@vite(['resources/js/data/spatialPlannings/form-create-update.js'])
@endsection

View File

@@ -0,0 +1,38 @@
@extends('layouts.vertical', ['subtitle' => 'Rencana Tata Ruang'])
@section('css')
@vite(['node_modules/gridjs/dist/theme/mermaid.min.css'])
@endsection
@section('content')
@include('layouts.partials/page-title', ['title' => 'Data', 'subtitle' => 'Rencana Tata Ruang'])
<div class="card">
<div class="card-header">
<h5 class="card-title">Daftar Rencana Tata Ruang</h5>
</div>
<div class="card-body">
<div class="row">
<div class="d-flex justify-content-end gap-10 pb-3">
<button class="btn btn-success me-2 width-lg btn-create" data-model="data/spatial-plannings">
<i class='bx bxs-file-plus'></i>
Create</button>
<button class="btn btn-primary width-lg btn-bulk-create" data-model="data/spatial-plannings">
<i class='bx bx-upload' ></i>
Bulk Create
</button>
</div>
<div>
<div id="spatial-planning-data-table"></div>
</div>
</div>
</div>
</div>
{{-- <div id="alert-container"></div> --}}
@endsection
@section('scripts')
@vite(['resources/js/data/spatialPlannings/data-spatialPlannings.js'])
@endsection

View File

@@ -71,7 +71,7 @@
</div> <!-- end row -->
<div class="toast-container position-fixed end-0 top-0 p-3">
<div id="toastUploadUmkm" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div id="toastUploadTourisms" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<div class="auth-logo me-auto">
</div>

View File

@@ -63,8 +63,9 @@
<input class="form-control" list="{{ $field }}Options" id="{{ $field }}" name="{{ $field }}"
value="{{ old($field, isset($modelInstance) ? $modelInstance->{$field} : '') }}" placeholder="Type to search..." oninput="fetchOptions('{{ $field }}')">
<datalist id="{{ $field }}Options"></datalist>
@elseif($fieldType == 'date')
<input type="date" id="{{ $field }}" name="{{ $field }}" class="form-control" value="{{ old($field, isset($modelInstance) ? $modelInstance->{$field} : '') }}">
@elseif($fieldType == 'date')
<input type="date" id="{{ $field }}" name="{{ $field }}" class="form-control"
value="{{ old($field, isset($modelInstance) && $modelInstance->{$field} ? \Carbon\Carbon::parse($modelInstance->{$field})->format('Y-m-d') : '') }}">
@else
<input type="{{ $fieldType }}" id="{{ $field }}" name="{{ $field }}" class="form-control" value="{{ old($field, isset($modelInstance) ? $modelInstance->{$field} : '') }}">
@endif

View File

@@ -29,6 +29,29 @@
</div>
</div>
<!-- Modal -->
<div class="modal fade modalGMaps" tabindex="-1"
aria-labelledby="confirmationModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<iframe
src=""
width="100%"
height="450"
style="border:0;"
allowfullscreen=""
loading="lazy">
</iframe>
</div>
</div>
</div>
</div>
{{-- <div id="alert-container"></div> --}}
@endsection

View File

@@ -7,7 +7,7 @@
@section('content')
@include('layouts.partials/page-title', ['title' => 'Report', 'subtitle' => 'Report Pariwisata'])
<input id="business_type_counts" type="hidden" value="{{ json_encode($businessTypeCounts) }}">
<input id="tourism_based_KBLI" type="hidden" value="{{ json_encode($tourismBasedKBLI) }}">
<div class="card">
<div class="card-header">
<h5 class="card-title">Laporan Pariwisata</h5>

View File

@@ -16,6 +16,7 @@ use App\Http\Controllers\Settings\SyncronizeController;
use App\Http\Controllers\Api\AdvertisementController;
use App\Http\Controllers\Api\UmkmController;
use App\Http\Controllers\Api\TourismController;
use App\Http\Controllers\Api\SpatialPlanningController;
use Illuminate\Support\Facades\Route;
Route::post('/login', [UsersController::class, 'login'])->name('api.user.login');
@@ -65,7 +66,11 @@ Route::group(['middleware' => 'auth:sanctum'], function (){
//tourism
Route::apiResource('tourisms', TourismController::class);
Route::post('/tourisms/import', [TourismController::class, 'importFromFile']);
Route::get('/download-template-tourism', [TourismController::class, 'downloadExcelTourism']);
Route::apiResource('spatial-plannings', SpatialPlanningController::class);
Route::post('/spatial-plannings/import', [SpatialPlanningController::class, 'importFromFile']);
Route::get('/download-template-spatialPlannings', [SpatialPlanningController::class, 'downloadExcelSpatialPlanning']);
// data-settings
Route::apiResource('/api-data-settings', DataSettingController::class);

View File

@@ -13,6 +13,7 @@ use App\Http\Controllers\Settings\SyncronizeController;
use App\Http\Controllers\Data\AdvertisementController;
use App\Http\Controllers\Data\UmkmController;
use App\Http\Controllers\Data\TourismController;
use App\Http\Controllers\Data\SpatialPlanningController;
use App\Http\Controllers\Report\ReportTourismController;
use Illuminate\Support\Facades\Route;
@@ -79,6 +80,14 @@ Route::group(['middleware' => 'auth'], function(){
// Rute khusus untuk create dan bulk-create
Route::get('/tourisms/create', [TourismController::class, 'create'])->name('tourisms.create');
Route::get('/tourisms/bulk-create', [TourismController::class, 'bulkCreate'])->name('tourisms.bulk-create');
// Resource route, kecuali create karena dibuat terpisah
Route::resource('/spatial-plannings', SpatialPlanningController::class)->except(['create', 'show']);
// Rute khusus untuk create dan bulk-create
Route::get('/spatial-plannings/create', [SpatialPlanningController::class, 'create'])->name('tourisms.create');
Route::get('/spatial-plannings/bulk-create', [SpatialPlanningController::class, 'bulkCreate'])->name('tourisms.bulk-create');
Route::resource('/business-industries',BusinessOrIndustriesController::class);
});

File diff suppressed because one or more lines are too long

View File

@@ -83,6 +83,7 @@ export default defineConfig({
"resources/js/data/tourisms/data-tourisms.js",
"resources/js/data/tourisms/form-create-update.js",
"resources/js/data/tourisms/form-upload.js",
"resources/js/report/tourisms/index.js",
],
refresh: true,
}),