Compare commits

...

10 Commits

Author SHA1 Message Date
arifal
080582f7ab add new menu peta in dashboard 2025-02-21 11:12:35 +07:00
arifal
91475aeead Merge branch 'dev' into feat/load-map-from-kmz 2025-02-21 10:43:06 +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
@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
arifal
5d50d6d6cc fix height card 2025-02-19 15:34:28 +07:00
arifal
39717d184c partial update create google map from kmz file 2025-02-19 14:31:12 +07:00
137 changed files with 1351 additions and 2816 deletions

View File

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

@@ -1,103 +0,0 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\ExcelUploadRequest;
use App\Http\Requests\SpatialPlanningsRequest;
use App\Http\Resources\SpatialPlanningsResource;
use App\Imports\SpatialPlanningImport;
use App\Models\SpatialPlanning;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
class SpatialPlanningsController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$query = SpatialPlanning::query()->orderBy('id', 'desc');
if ($request->has("search") &&!empty($request->get("search"))) {
$query = $query->where("name", "LIKE", "%{$request->get("search")}%")
->orWhere("nomor", "LIKE", "%{$request->get("search")}%");
}
return SpatialPlanningsResource::collection($query->paginate());
}
public function store(SpatialPlanningsRequest $request)
{
try{
$validated = $request->validated();
$data = SpatialPlanning::create($validated);
return response()->json(['message' => 'Successfully created', new SpatialPlanningsResource($data)]);
}catch(\Exception $e){
return response()->json([
'message' => $e->getMessage()
], 500);
}
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(SpatialPlanningsRequest $request, string $id)
{
try{
$validated = $request->validated();
$data = SpatialPlanning::find($id);
$data->update($validated);
return response()->json(['message' => 'Successfully updated', new SpatialPlanningsResource($data)]);
}catch(\Exception $e){
return response()->json([
'message' => $e->getMessage()
], 500);
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
try{
SpatialPlanning::destroy($id);
return response()->json([
'message' => 'Successfully deleted'
], 200);
}catch(\Exception $e){
return response()->json([
'message' => $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 SpatialPlanningImport, $file);
return response()->json([
'message' => 'Successfully imported'
], 200);
}catch(\Exception $e){
return response()->json([
'error' => $e->getMessage()
], 500);
}
}
}

View File

@@ -25,6 +25,13 @@ class TourismController extends Controller
$search = $request->input('search', ''); $search = $request->input('search', '');
$query = Tourism::query(); $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 = $query->paginate($perPage);
$tourisms->getCollection()->transform(function ($tourisms) { $tourisms->getCollection()->transform(function ($tourisms) {
@@ -36,8 +43,14 @@ class TourismController extends Controller
return $tourisms; 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([ return response()->json([
'data' => TourismResource::collection($tourisms), 'data' => $data,
'meta' => [ 'meta' => [
'total' => $tourisms->total(), 'total' => $tourisms->total(),
'per_page' => $tourisms->perPage(), 'per_page' => $tourisms->perPage(),
@@ -127,4 +140,18 @@ class TourismController extends Controller
return response()->noContent(); 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(); $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 = $query->paginate($perPage);
$umkm->getCollection()->transform(function ($umkm) { $umkm->getCollection()->transform(function ($umkm) {
@@ -47,8 +58,14 @@ class UmkmController extends Controller
return $umkm; 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([ return response()->json([
'data' => UmkmResource::collection($umkm), 'data' => $data,
'meta' => [ 'meta' => [
'total' => $umkm->total(), 'total' => $umkm->total(),
'per_page' => $umkm->perPage(), 'per_page' => $umkm->perPage(),
@@ -176,7 +193,7 @@ class UmkmController extends Controller
public function downloadExcelUmkm() public function downloadExcelUmkm()
{ {
$filePath = storage_path('app/public/templates/template_umkm.xlsx'); $filePath = public_path('templates/template_umkm.xlsx');
// Cek apakah file ada // Cek apakah file ada
if (!file_exists($filePath)) { 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

@@ -53,7 +53,7 @@ class TourismController extends Controller
public function edit($id) public function edit($id)
{ {
$title = 'Pariwisata'; $title = 'Pariwisata';
$subtitle = 'Create Data'; $subtitle = 'Update Data';
$modelInstance = Tourism::find($id); $modelInstance = Tourism::find($id);
// Pastikan model ditemukan // Pastikan model ditemukan

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class GoogleApisController extends Controller
{
public function index(){
return view('maps.google-api');
}
}

View File

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

View File

@@ -40,4 +40,40 @@ class AdvertisementRequest extends FormRequest
'contact' => 'required|string', '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

@@ -49,4 +49,85 @@ class TourismRequest extends FormRequest
'tki' => '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,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

@@ -3,75 +3,61 @@
namespace App\Imports; namespace App\Imports;
use App\Models\SpatialPlanning; use App\Models\SpatialPlanning;
use Carbon\Carbon;
use DateTime;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Concerns\ToCollection; use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithMultipleSheets; use Illuminate\Support\Facades\DB;
use DateTime;
use Carbon\Carbon;
class SpatialPlanningImport implements ToCollection, WithMultipleSheets class SpatialPlanningImport implements ToCollection
{ {
protected static $processed = false;
/** /**
* @param Collection $collection * Process each row in the file
*/ */
public function collection(Collection $collection) public function collection(Collection $rows)
{ {
$months = [ if (self::$processed) {
"Januari" => "January", "Februari" => "February", "Maret" => "March", return;
"April" => "April", "Mei" => "May", "Juni" => "June", }
"Juli" => "July", "Agustus" => "August", "September" => "September", self::$processed = true;
"Oktober" => "October", "November" => "November", "Desember" => "December"
];
$collection->skip(2)->each(function ($row) use ($months) { if ($rows->isEmpty())
if (empty(array_filter($row->toArray()))) { {
return; return;
} }
if (!isset($row[6]) || empty($row[6])) { //cari header secara otomatis
$header = $rows->first();
$headerIndex = collect($header)->search(fn($value) => !empty($value));
// Pastikan header ditemukan
if ($headerIndex === false) {
return; return;
} }
if(!SpatialPlanning::where("nomor", $row[6])->exists()){ foreach ($rows->skip(1) as $row) {
$clean_nomor = str_replace('\\','',$row[6]); $dateValue = trim($row[7]);
$date_string = isset($row[7]) ? trim($row[7]) : null; info($dateValue);
$clean_sp_date = null; $parsedDate = Carbon::createFromFormat('Y-m-d', $dateValue)->format('Y-m-d');
if ($date_string) { info($parsedDate);
if(is_numeric($date_string)) {
$clean_sp_date = Carbon::createFromFormat('Y-m-d', '1900-01-01')->addDays($date_string - 2)->format('Y-m-d');
}else{
foreach ($months as $id => $en) {
$date_string = str_replace($id, $en, $date_string);
}
$formats = ['j F Y', 'd F Y', 'j-M-Y', 'd-M-Y']; $dataToInsert[] = [
foreach ($formats as $format) {
$date = DateTime::createFromFormat($format, $date_string);
if ($date) {
$clean_sp_date = $date->format('Y-m-d');
break;
}
}
}
}
SpatialPlanning::create([
'name'=>$row[1], 'name'=>$row[1],
'kbli'=>$row[2], 'kbli'=>$row[2],
'kegiatan' => $row[3], 'activities'=>$row[3],
'luas' => $row[4], 'area'=>$row[4],
'lokasi' => $row[5], 'location'=>$row[5],
'nomor' => $clean_nomor, 'number'=>$row[6],
'sp_date' => $clean_sp_date, 'date'=>$parsedDate,
]);
}
});
}
public function sheets(): array {
return [
0 => $this
]; ];
} }
if(!empty($dataToInsert)) {
SpatialPlanning::insert($dataToInsert);
} else {
return;
}
}
} }

View File

@@ -65,13 +65,6 @@ class TourismImport implements ToCollection
// ambill village code yang village_name sama dengan $villageName // ambill village code yang village_name sama dengan $villageName
$villageCode = $listTrueVillage[$villageName]['village_code'] ?? '000000'; $villageCode = $listTrueVillage[$villageName]['village_code'] ?? '000000';
// if (empty($row[16])) {
// info("Data kosong");
// } else {
// info("Baris ke- | Nilai: " . $row[16]);
// }
$excelSerialDate = $row[16]; $excelSerialDate = $row[16];
if (is_numeric($excelSerialDate)) { if (is_numeric($excelSerialDate)) {
$projectSubmissionDate = Carbon::createFromFormat('Y-m-d', '1899-12-30') $projectSubmissionDate = Carbon::createFromFormat('Y-m-d', '1899-12-30')
@@ -82,8 +75,6 @@ class TourismImport implements ToCollection
->format('Y-m-d H:i:s'); ->format('Y-m-d H:i:s');
} }
info("Tanggal dikonversi: " . $projectSubmissionDate);
$dataToInsert[] = [ $dataToInsert[] = [
'project_id' => $row[1], 'project_id' => $row[1],
'project_type_id' => $row[2], 'project_type_id' => $row[2],

View File

@@ -4,16 +4,34 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model; 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 class SpatialPlanning extends Model
{ {
protected $table = "spatial_plannings";
protected $fillable = [ protected $perPage = 20;
'name',
'kbli', /**
'kegiatan', * The attributes that are mass assignable.
'luas', *
'lokasi', * @var array<int, string>
'nomor', */
'sp_date' protected $fillable = ['name', 'kbli', 'activities', 'area', 'location', 'number', 'date'];
];
} }

View File

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

View File

@@ -1,34 +0,0 @@
<?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_plannings', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('kbli');
$table->text('kegiatan');
$table->decimal('luas',18,2);
$table->text('lokasi');
$table->string('nomor')->unique();
$table->date('sp_date');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('spatial_plannings');
}
};

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

@@ -116,6 +116,13 @@ class UsersRoleMenuSeeder extends Seeder
"parent_id" => $dashboard->id, "parent_id" => $dashboard->id,
"sort_order" => 3, "sort_order" => 3,
], ],
[
"name" => "PETA",
"url" => "dashboard.maps",
"icon" => null,
"parent_id" => $dashboard->id,
"sort_order" => 4,
],
[ [
"name" => "Users", "name" => "Users",
"url" => "users.index", "url" => "users.index",
@@ -188,7 +195,7 @@ class UsersRoleMenuSeeder extends Seeder
], ],
[ [
"name" => "Tata Ruang", "name" => "Tata Ruang",
"url" => "spatial-plannings", "url" => "spatial-plannings.index",
"icon" => null, "icon" => null,
"parent_id" => $data->id, "parent_id" => $data->id,
"sort_order" => 6, "sort_order" => 6,
@@ -229,6 +236,7 @@ class UsersRoleMenuSeeder extends Seeder
$lack_of_potentials = Menu::where('name', 'Dashboard Potensi')->first(); $lack_of_potentials = Menu::where('name', 'Dashboard Potensi')->first();
$spatial_plannings = Menu::where('name', 'Tata Ruang')->first(); $spatial_plannings = Menu::where('name', 'Tata Ruang')->first();
$pdam = Menu::where('name', 'PDAM')->first(); $pdam = Menu::where('name', 'PDAM')->first();
$peta = Menu::where('name', 'PETA')->first();
// Superadmin gets all menus // Superadmin gets all menus
$superadmin->menus()->sync([ $superadmin->menus()->sync([
@@ -256,6 +264,7 @@ class UsersRoleMenuSeeder extends Seeder
$lack_of_potentials->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], $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], $pdam->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
$peta->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
]); ]);
// Admin gets limited menus // Admin gets limited menus

Binary file not shown.

Binary file not shown.

View File

@@ -28,12 +28,7 @@ document.addEventListener("DOMContentLoaded", function () {
data[key] = value; 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"); const url = form.getAttribute("action");
console.log("Ini adalah url dari form action", url);
const method = isEdit ? "PUT" : "POST"; const method = isEdit ? "PUT" : "POST";
@@ -49,7 +44,6 @@ document.addEventListener("DOMContentLoaded", function () {
}) })
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
console.log("Response data:", data);
if (!data.errors) { if (!data.errors) {
// Remove existing icon (if any) before adding the new one // Remove existing icon (if any) before adding the new one
if (authLogo) { if (authLogo) {
@@ -74,11 +68,11 @@ document.addEventListener("DOMContentLoaded", function () {
toast.classList.add('show'); // Show the toast toast.classList.add('show'); // Show the toast
setTimeout(() => { setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000); }, 2000);
setTimeout(() => { setTimeout(() => {
window.location.href = '/data/advertisements'; window.location.href = '/data/advertisements';
}, 3000); }, 1000);
} else { } else {
if (authLogo) { if (authLogo) {
// Hapus ikon yang sudah ada jika ada // Hapus ikon yang sudah ada jika ada
@@ -96,21 +90,21 @@ document.addEventListener("DOMContentLoaded", function () {
// Tambahkan ikon ke dalam auth-logo // Tambahkan ikon ke dalam auth-logo
authLogo.appendChild(icon); 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 // Enable button and reset its text on error
modalButton.disabled = false; modalButton.disabled = false;
modalButton.innerHTML = isEdit ? "Update" : "Create"; 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(() => { setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000); }, 3000);
} }
}) })
.catch(error => { .catch(errors => {
console.error("Error:", error);
if (authLogo) { if (authLogo) {
// Hapus ikon yang sudah ada jika ada // Hapus ikon yang sudah ada jika ada
const existingIcon = authLogo.querySelector('.bx'); const existingIcon = authLogo.querySelector('.bx');
@@ -127,14 +121,14 @@ document.addEventListener("DOMContentLoaded", function () {
// Tambahkan ikon ke dalam auth-logo // Tambahkan ikon ke dalam auth-logo
authLogo.appendChild(icon); 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 // Enable button and reset its text on error
modalButton.disabled = false; modalButton.disabled = false;
modalButton.innerHTML = isEdit ? "Update" : "Create"; 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(() => { setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000); }, 3000);
@@ -144,7 +138,6 @@ document.addEventListener("DOMContentLoaded", function () {
// Fungsi fetchOptions untuk autocomplete server-side // Fungsi fetchOptions untuk autocomplete server-side
window.fetchOptions = function (field) { window.fetchOptions = function (field) {
let inputValue = document.getElementById(field).value; let inputValue = document.getElementById(field).value;
console.log("Query Value:", inputValue); // Debugging log
if (inputValue.length < 2) return; if (inputValue.length < 2) return;
let districtValue = document.getElementById("district_name").value; // Ambil kecamatan terpilih 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,6 +5,7 @@ import GlobalConfig from "../../global-config.js";
import GeneralTable from "../../table-generator.js"; import GeneralTable from "../../table-generator.js";
const dataTourismsColumns = [ const dataTourismsColumns = [
"No",
"Nama Perusahaan", "Nama Perusahaan",
"Nama Proyek", "Nama Proyek",
"Alamat Usaha", "Alamat Usaha",
@@ -54,6 +55,7 @@ document.addEventListener("DOMContentLoaded", () => {
table.processData = function (data) { table.processData = function (data) {
return data.data.map((item) => { return data.data.map((item) => {
return [ return [
item.no,
item.business_name, item.business_name,
item.project_name, item.project_name,
item.business_address, item.business_address,

View File

@@ -28,12 +28,7 @@ document.addEventListener("DOMContentLoaded", function () {
data[key] = value; 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"); const url = form.getAttribute("action");
console.log("Ini adalah url dari form action", url);
const method = isEdit ? "PUT" : "POST"; const method = isEdit ? "PUT" : "POST";
@@ -49,7 +44,6 @@ document.addEventListener("DOMContentLoaded", function () {
}) })
.then((response) => response.json()) .then((response) => response.json())
.then((data) => { .then((data) => {
console.log("Response data:", data);
if (!data.errors) { if (!data.errors) {
// Remove existing icon (if any) before adding the new one // Remove existing icon (if any) before adding the new one
if (authLogo) { if (authLogo) {
@@ -113,7 +107,6 @@ document.addEventListener("DOMContentLoaded", function () {
} }
}) })
.catch((error) => { .catch((error) => {
console.error("Error:", error);
if (authLogo) { if (authLogo) {
// Hapus ikon yang sudah ada jika ada // Hapus ikon yang sudah ada jika ada
const existingIcon = authLogo.querySelector(".bx"); const existingIcon = authLogo.querySelector(".bx");
@@ -148,7 +141,6 @@ document.addEventListener("DOMContentLoaded", function () {
// Fungsi fetchOptions untuk autocomplete server-side // Fungsi fetchOptions untuk autocomplete server-side
window.fetchOptions = function (field) { window.fetchOptions = function (field) {
let inputValue = document.getElementById(field).value; let inputValue = document.getElementById(field).value;
console.log("Query Value:", inputValue); // Debugging log
if (inputValue.length < 2) return; if (inputValue.length < 2) return;
let districtValue = document.getElementById("district_name").value; // Ambil kecamatan terpilih 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 // Add event listener to download file template
document.getElementById('downloadtemptourisms').addEventListener('click', function() { document.getElementById('downloadtemptourisms').addEventListener('click', function() {
var url = `${GlobalConfig.apiHost}/api/download-template-umkm`; var url = `${GlobalConfig.apiHost}/api/download-template-tourism`;
fetch(url, { fetch(url, {
method: 'GET', method: 'GET',
headers: { headers: {
@@ -105,11 +105,12 @@ document.getElementById('downloadtemptourisms').addEventListener('click', functi
} }
}) })
.then((blob) => { .then((blob) => {
console.log(blob);
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
const a = document.createElement('a'); const a = document.createElement('a');
a.style.display = 'none'; a.style.display = 'none';
a.href = url; a.href = url;
a.download = 'template_tourisms.xlsx'; a.download = 'template_pariwisata.xlsx';
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
window.URL.revokeObjectURL(url); window.URL.revokeObjectURL(url);
@@ -122,7 +123,7 @@ document.getElementById('downloadtemptourisms').addEventListener('click', functi
// Function to show toast // Function to show toast
function showToast(iconClass, iconColor, message) { function showToast(iconClass, iconColor, message) {
const toastElement = document.getElementById('toastUploadUmkm'); const toastElement = document.getElementById('toastUploadTourisms');
const toastBody = toastElement.querySelector('.toast-body'); const toastBody = toastElement.querySelector('.toast-body');
const toastHeader = toastElement.querySelector('.toast-header'); const toastHeader = toastElement.querySelector('.toast-header');

View File

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

View File

@@ -28,12 +28,7 @@ document.addEventListener("DOMContentLoaded", function () {
data[key] = value; 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"); const url = form.getAttribute("action");
console.log("Ini adalah url dari form action", url);
const method = isEdit ? "PUT" : "POST"; const method = isEdit ? "PUT" : "POST";
@@ -74,11 +69,11 @@ document.addEventListener("DOMContentLoaded", function () {
toast.classList.add('show'); // Show the toast toast.classList.add('show'); // Show the toast
setTimeout(() => { setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000); }, 2000);
setTimeout(() => { setTimeout(() => {
window.location.href = '/data/umkm'; window.location.href = '/data/umkm';
}, 3000); }, 1000);
} else { } else {
if (authLogo) { if (authLogo) {
// Hapus ikon yang sudah ada jika ada // Hapus ikon yang sudah ada jika ada
@@ -96,14 +91,16 @@ document.addEventListener("DOMContentLoaded", function () {
// Tambahkan ikon ke dalam auth-logo // Tambahkan ikon ke dalam auth-logo
authLogo.appendChild(icon); 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 // Enable button and reset its text on error
modalButton.disabled = false; modalButton.disabled = false;
modalButton.innerHTML = isEdit ? "Update" : "Create"; 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(() => { setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000); }, 3000);
@@ -127,14 +124,15 @@ document.addEventListener("DOMContentLoaded", function () {
// Tambahkan ikon ke dalam auth-logo // Tambahkan ikon ke dalam auth-logo
authLogo.appendChild(icon); 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 // Enable button and reset its text on error
modalButton.disabled = false; modalButton.disabled = false;
modalButton.innerHTML = isEdit ? "Update" : "Create"; 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(() => { setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000); }, 3000);
@@ -144,7 +142,6 @@ document.addEventListener("DOMContentLoaded", function () {
// Fungsi fetchOptions untuk autocomplete server-side // Fungsi fetchOptions untuk autocomplete server-side
window.fetchOptions = function (field) { window.fetchOptions = function (field) {
let inputValue = document.getElementById(field).value; let inputValue = document.getElementById(field).value;
console.log("Query Value:", inputValue); // Debugging log
if (inputValue.length < 2) return; if (inputValue.length < 2) return;
let districtValue = document.getElementById("district_name").value; // Ambil kecamatan terpilih let districtValue = document.getElementById("district_name").value; // Ambil kecamatan terpilih

View File

@@ -1,69 +0,0 @@
import flatpickr from "flatpickr";
class CreateSpatialPlannings {
constructor() {
this.initCreateSpatial();
}
initCreateSpatial() {
const toastNotification = document.getElementById("toastNotification");
const toast = new bootstrap.Toast(toastNotification);
document
.getElementById("btnCreateSpatialPlannings")
.addEventListener("click", async function () {
let submitButton = this;
let spinner = document.getElementById("spinner");
let form = document.getElementById(
"formCreateSpatialPlannings"
);
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/spatial-plannings";
}, 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 CreateSpatialPlannings();
});

View File

@@ -1,156 +0,0 @@
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 SpatialPlannings {
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-spatial-plannings"
);
if (deleteButton) {
event.preventDefault();
await this.handleDelete(deleteButton);
}
});
}
initTableSpatialPlannings() {
let tableContainer = document.getElementById("table-spatial-plannings");
// Create a new Grid.js instance only if it doesn't exist
this.table = new Grid({
columns: [
"ID",
"Name",
"KBLI",
"Kegiatan",
"Luas",
"Lokasi",
"Nomor",
"Date",
{
name: "Action",
formatter: (cell) =>
gridjs.html(`
<div class="d-flex justify-content-center gap-2">
<a href="/data/spatial-plannings/${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 id="btn-delete-spatial-plannings" data-id="${cell}" class="btn btn-sm btn-red btn-delete-spatial-plannings 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/spatial-plannings`,
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.name,
item.kbli,
item.kegiatan,
item.luas,
item.lokasi,
item.nomor,
item.sp_date,
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/spatial-plannings/${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 SpatialPlannings();
});

View File

@@ -1,67 +0,0 @@
class UpdateSpatialPlannings {
constructor() {
this.initUpdateSpatial();
}
initUpdateSpatial() {
const toastNotification = document.getElementById("toastNotification");
const toast = new bootstrap.Toast(toastNotification);
document
.getElementById("btnUpdateSpatialPlannings")
.addEventListener("click", async function () {
let submitButton = this;
let spinner = document.getElementById("spinner");
let form = document.getElementById(
"formUpdateSpatialPlannings"
);
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/spatial-plannings";
}, 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 UpdateSpatialPlannings();
});

View File

@@ -1,83 +0,0 @@
import { Dropzone } from "dropzone";
Dropzone.autoDiscover = false;
class UploadSpatialPlannings {
constructor() {
this.spatialDropzone = null;
this.formElement = document.getElementById(
"formUploadSpatialPlannings"
);
this.uploadButton = document.getElementById("submit-upload");
this.spinner = document.getElementById("spinner");
if (!this.formElement) {
console.error(
"Element formUploadSpatialPlannings 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/spatial-plannings";
}, 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 UploadSpatialPlannings().init();
});

View File

@@ -1,15 +0,0 @@
<?php
namespace [% namespace %];
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
[% response_methods %]
}

View File

@@ -1 +0,0 @@
return new [% api_resource_class %]($[% model_name_singular_variable %], [% model_was_deleted %]);

View File

@@ -1,4 +0,0 @@
return $this->successResponse(
[% model_was_deleted %],
$this->transform($[% model_name_singular_variable %])
);

View File

@@ -1 +0,0 @@
return new [% api_resource_collection_class %]($[% model_name_plural_variable %], [% models_were_retrieved %]);

View File

@@ -1,26 +0,0 @@
$[% data_variable %] = $[% model_name_plural_variable %]->transform(function ($[% model_name_singular_variable %]) {
return $this->transform($[% model_name_singular_variable %]);
});
return $this->successResponse(
[% models_were_retrieved %],
$[% data_variable %],
[
'links' => [
'first' => $[% model_name_plural_variable %]->url(1),
'last' => $[% model_name_plural_variable %]->url($[% model_name_plural_variable %]->lastPage()),
'prev' => $[% model_name_plural_variable %]->previousPageUrl(),
'next' => $[% model_name_plural_variable %]->nextPageUrl(),
],
'meta' =>
[
'current_page' => $[% model_name_plural_variable %]->currentPage(),
'from' => $[% model_name_plural_variable %]->firstItem(),
'last_page' => $[% model_name_plural_variable %]->lastPage(),
'path' => $[% model_name_plural_variable %]->resolveCurrentPath(),
'per_page' => $[% model_name_plural_variable %]->perPage(),
'to' => $[% model_name_plural_variable %]->lastItem(),
'total' => $[% model_name_plural_variable %]->total(),
],
]
);

View File

@@ -1 +0,0 @@
return new [% api_resource_class %]($[% model_name_singular_variable %], [% model_was_retrieved %]);

View File

@@ -1,4 +0,0 @@
return $this->successResponse(
[% model_was_retrieved %],
$this->transform($[% model_name_singular_variable %])
);

View File

@@ -1 +0,0 @@
return new [% api_resource_class %]($[% model_name_singular_variable %], [% model_was_added %]);

View File

@@ -1,4 +0,0 @@
return $this->successResponse(
[% model_was_added %],
$this->transform($[% model_name_singular_variable %])
);

View File

@@ -1 +0,0 @@
return new [% api_resource_class %]($[% model_name_singular_variable %], [% model_was_updated %]);

View File

@@ -1,4 +0,0 @@
return $this->successResponse(
[% model_was_updated %],
$this->transform($[% model_name_singular_variable %])
);

View File

@@ -1,14 +0,0 @@
/**
* Get an error response
*
* @param mix $message
*
* @return Illuminate\Http\Response
*/
protected function errorResponse($message)
{
return response()->json([
'errors' => (array) $message,
'success' => false,
], 422);
}

View File

@@ -1,16 +0,0 @@
/**
* Gets a new validator instance with the defined rules.
*
* @param [% request_fullname %] $request
*
* @return Illuminate\Support\Facades\Validator
*/
protected function getValidator(Request $request)
{
$rules = [
[% validation_rules %]
];
[% file_validation_snippet %]
return Validator::make($request->all(), $rules);
}

View File

@@ -1,18 +0,0 @@
/**
* Get a success response
*
* @param mix $message
* @param mix $data
* @param array $meta
*
* @return Illuminate\Http\Response
*/
protected function successResponse($message, $data, array $meta = [])
{
return response()->json(
array_merge([
'data' => $data,
'message' => $message,
'success' => true,
], $meta), 200);
}

View File

@@ -1,13 +0,0 @@
/**
* Transform the giving [% model_name %] to public friendly array
*
* @param [% use_full_model_name %] $[% model_name_singular_variable %]
*
* @return array
*/
protected function [% transform_method_name %]([% model_name_class %] $[% model_name_singular_variable %])
{
return [
[% model_api_array %]
];
}

View File

@@ -1,5 +0,0 @@
$validator = $this->getValidator($request);
if ($validator->fails()) {
return $this->errorResponse($validator->errors()->all());
}

View File

@@ -1,104 +0,0 @@
<?php
namespace [% namespace %];
[% use_command_placeholder %]
use Exception;
class [% controller_name %] [% controller_extends %]
{
[% constructor %]
/**
* Display a listing of the assets.
*
* @return Illuminate\View\View
*/
public function index()
{
$[% model_name_plural_variable %] = [% model_name_class %]::[% with_relations_for_index %]paginate([% models_per_page %]);
[% index_return_success %]
}
/**
* Store a new [% model_name %] in the storage.
*
* @param [% request_fullname %] [% request_variable %]
*
* @return Illuminate\Http\Response
*/
public function store([% type_hinted_request_name %])
{
try {
[% validator_request %]
$[% data_variable %] = [% call_get_data %];
[% on_store_setter %]
$[% model_name_singular_variable %] = [% model_name_class %]::create($[% data_variable %]);
[% store_return_success %]
} catch (Exception $exception) {
return $this->errorResponse([% unexpected_error %]);
}
}
/**
* Display the specified [% model_name %].
*
* @param int $id
*
* @return Illuminate\Http\Response
*/
public function show($id)
{
$[% model_name_singular_variable %] = [% model_name_class %]::[% with_relations_for_show %]findOrFail($id);
[% show_return_success %]
}
/**
* Update the specified [% model_name %] in the storage.
*
* @param int $id
* @param [% request_fullname %] [% request_variable %]
*
* @return Illuminate\Http\Response
*/
public function update($id, [% type_hinted_request_name %])
{
try {
[% validator_request %]
$[% data_variable %] = [% call_get_data %];
[% on_update_setter %]
$[% model_name_singular_variable %] = [% model_name_class %]::findOrFail($id);
$[% model_name_singular_variable %]->update($[% data_variable %]);
[% update_return_success %]
} catch (Exception $exception) {
return $this->errorResponse([% unexpected_error %]);
}
}
/**
* Remove the specified [% model_name %] from the storage.
*
* @param int $id
*
* @return Illuminate\Http\Response
*/
public function destroy($id)
{
try {
$[% model_name_singular_variable %] = [% model_name_class %]::findOrFail($id);
$[% model_name_singular_variable %]->delete();
[% destroy_return_success %]
} catch (Exception $exception) {
return $this->errorResponse([% unexpected_error %]);
}
}
[% get_validator_method %]
[% get_data_method %]
[% upload_method %]
[% transform_method %]
[% response_methods %]
}

View File

@@ -1,21 +0,0 @@
<?php
namespace [% namespace %];
[% use_command_placeholder %]
class [% controller_name %] [% controller_extends %]
{
[% constructor %]
/**
* Display the documentation which corresponds to the giving version.
*
* @return Illuminate\View\View
*/
public function index($version)
{
$viewName = sprintf('[% view_access_fullname %]index', $this->getVersion($version));
return view($viewName);
}
}

View File

@@ -1,20 +0,0 @@
<?php
namespace [% namespace %];
[% use_command_placeholder %]
class [% controller_name %] [% controller_extends %]
{
[% constructor %]
/**
* Display the documentation's view.
*
* @return Illuminate\View\View
*/
public function index()
{
return view('[% view_access_fullname %]index');
}
}

View File

@@ -1 +0,0 @@
<span class="label label-danger" title="[% this_parameter_must_be_present_in_the_request %]">[% required_title %]</span>

View File

@@ -1,11 +0,0 @@
<tr>
<td>Authorization</td>
<td>[% string_title %]</td>
<td>
<span class="label label-primary" title="[% this_parameter_is_an_http_header %]">[% header_title %]</span>
</td>
<td>[% access_token_with_bearer %]</td>
@if(isset($showValidation) && $showValidation)
<td></td>
@endif
</tr>

View File

@@ -1,16 +0,0 @@
<h4 class="text-danger"><strong>401 - Unauthorized</strong></h4>
<p class="text-muted">[% the_user_does_not_have_permission_to_access_the_requested_resource %]</p>
<table class="table table-stripped">
<tbody>
<tr>
<td>success</td>
<td>[% boolean_title %]</td>
<td>[% indicate_whether_the_request_was_successful_or_not %]</td>
</tr>
<tr>
<td>error</td>
<td>[% array_of_strings %]</td>
<td>[% the_error_message %]</td>
</tr>
</tbody>
</table>

View File

@@ -1,16 +0,0 @@
<h4 class="text-danger"><strong>202 - Accepted</strong></h4>
<p class="text-muted">[% the_requested_model_does_not_exists %]</p>
<table class="table table-stripped">
<tbody>
<tr>
<td>success</td>
<td>[% boolean_title %]</td>
<td>[% indicate_whether_the_request_was_successful_or_not %]</td>
</tr>
<tr>
<td>error</td>
<td>[% array_of_strings %]</td>
<td>[% the_error_message %]</td>
</tr>
</tbody>
</table>

View File

@@ -1,16 +0,0 @@
<h4 class="text-danger"><strong>422 - Unprocessable Entity</strong></h4>
<p class="text-muted">[% the_request_failed_validation %]</p>
<table class="table table-stripped">
<tbody>
<tr>
<td>success</td>
<td>[% boolean_title %]</td>
<td>[% indicate_whether_the_request_was_successful_or_not %]</td>
</tr>
<tr>
<td>errors</td>
<td>[% array_of_strings %]</td>
<td>[% list_of_the_invalid_errors %]</td>
</tr>
</tbody>
</table>

View File

@@ -1,5 +0,0 @@
<tr>
<td>[% field_name %]</td>
<td>[% field_type_title %]</td>
<td>[% api_field_description %]</td>
</tr>

View File

@@ -1,12 +0,0 @@
<tr>
<td>[% field_name %]</td>
<td>[% field_type_title %]</td>
<td><span class="label label-default" title="[% this_parameter_is_part_of_the_body %]">[% body_title %]</span></td>
<td>[% api_field_description %]</td>
@if($showValidation)
<td>
[% validation_rule_required %]
<span>[% validation_rules %]</span>
</td>
@endif
</tr>

View File

@@ -1,37 +0,0 @@
<?php
$showValidation = (isset($withValidation) && $withValidation) ? true : false;
?>
<table class="table table-stripped">
<thead>
<tr>
<th>[% parameter_name_title %]</th>
<th>[% data_type_title %]</th>
<th>[% parameter_type_title %]</th>
<th>[% description_title %]</th>
@if($showValidation)
<th>[% validation_title %]</th>
@endif
</tr>
</thead>
<tbody>
[% include_parameter_for_authorized_request %]
@if(isset($withPathId) && $withPathId)
<tr>
<td>[% model_name %]</td>
<td>[% primary_key_type_title %]</td>
<td><span class="label label-info" title="[% this_parameter_is_part_of_the_path %]">[% path_title %]</span></td>
<td>[% the_id_of_the_model %]</td>
@if($showValidation)
<td>
[% validation_rule_required %]
</td>
@endif
</tr>
@endif
[% fields_list_for_body %]
</tbody>
</table>

View File

@@ -1,14 +0,0 @@
<table class="table table-stripped">
<thead>
<tr>
<th>[% parameter_name_title %]</th>
<th>[% data_type_title %]</th>
<th>[% parameter_type_title %]</th>
<th>[% description_title %]</th>
</tr>
</thead>
<tbody>
[% include_parameter_for_authorized_request %]
</tbody>
</table>

View File

@@ -1,5 +0,0 @@
<tr>
<td>[% field_name %]</td>
<td>[% field_type_title %]</td>
<td>[% api_field_description %]</td>
</tr>

View File

@@ -1,12 +0,0 @@
<table class="table table-stripped">
<thead>
<tr>
<th>[% name_title %]</th>
<th>[% type_title %]</th>
<th>[% description_title %]</th>
</tr>
</thead>
<tbody>
[% fields_list_for_body %]
</tbody>
</table>

View File

@@ -1,21 +0,0 @@
<h4 class="text-success"><strong>200 - Ok</strong></h4>
<p class="text-muted">[% request_was_successful %]</p>
<table class="table table-stripped">
<tbody>
<tr>
<td>success</td>
<td>[% boolean_title %]</td>
<td>[% indicate_whether_the_request_was_successful_or_not %]</td>
</tr>
<tr>
<td>message</td>
<td>[% string_title %]</td>
<td>[% the_success_message %]</td>
</tr>
<tr>
<td>data</td>
<td>[% array_title %]</td>
<td>[% the_key_is_the_model_property_and_the_value_is_the_model_value %]</td>
</tr>
</tbody>
</table>

View File

@@ -1,386 +0,0 @@
@extends('[% layout_name %]')
@section('content')
<h2>[% model_plural %]</h2>
[% general_description %]
<hr>
<h2>[% available_resources %]</h2>
<div class="card mb-3" id="index-documentation">
<div class="card-header text-bg-primary d-flex justify-content-between align-items-center p-3">
<div>
<span class="">GET</span>
<span><strong>/{{ Route::getRoutes()->getByName('[% index_route_name %]')->uri() }}</strong></span>
<p class="mb-0">[% index_route_description %]</p>
</div>
<div>
<button type="button" data-bs-toggle="collapse" data-bs-target="#index" aria-controls="index" class="btn btn-primary btn-sm" aria-expanded="false">
<span class="fa-solid fa-chevron-down"></span>
</button>
</div>
</div>
<div class="card-body collapse" id="index">
<h3><strong>[% request_title %]</strong></h3>
[% authorized_request_for_index %]
<hr>
<h3><strong>[% response_title %]</strong></h3>
<p>[% index_route_response_description %]</p>
<p></p>
<h4><strong class="text-success">200 - Ok</strong></h4>
<p class="text-muted">[% request_was_successful %]</p>
<table class="table table-stripped">
<tbody>
<tr>
<td>success</td>
<td>[% boolean_title %]</td>
<td>Was the request successful or not.</td>
</tr>
<tr>
<td>message</td>
<td>[% string_title %]</td>
<td>[% the_success_message %]</td>
</tr>
<tr>
<td>data</td>
<td>[% array_title %]</td>
<td>
[% the_key_is_the_model_property_and_the_value_is_the_model_value %]
</td>
</tr>
<tr>
<td>links</td>
<td>[% array_title %]</td>
<td>
<table class="table table-stripped">
<thead>
<tr>
<th class="col-md-2">[% key_title %]</th>
<th class="col-md-2">[% data_type_title %]</th>
<th class="col-md-8">[% description_title %]</th>
</tr>
</thead>
<tbody>
<tr>
<td>first</td>
<td>[% string_title %]</td>
<td>[% link_to_retrieve_first_page %]</td>
</tr>
<tr>
<td>last</td>
<td>[% string_title %]</td>
<td>[% link_to_retrieve_last_page %]</td>
</tr>
<tr>
<td>prev</td>
<td>[% string_title %]</td>
<td>[% link_to_retrieve_previous_page %]</td>
</tr>
<tr>
<td>next</td>
<td>[% string_title %]</td>
<td>[% link_to_retrieve_next_page %]</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td>meta</td>
<td>[% array_title %]</td>
<td>
<table class="table table-stripped">
<thead>
<tr>
<th class="col-md-2">[% key_title %]</th>
<th class="col-md-2">[% data_type_title %]</th>
<th class="col-md-8">[% description_title %]</th>
</tr>
</thead>
<tbody>
<tr>
<td>current_page</td>
<td>[% integer_title %]</td>
<td>[% the_number_of_current_page %]</td>
</tr>
<tr>
<td>from</td>
<td>[% integer_title %]</td>
<td>[% the_index_of_the_first_retrieved_item %]</td>
</tr>
<tr>
<td>last_page</td>
<td>[% integer_title %]</td>
<td>[% the_number_of_the_last_page %]</td>
</tr>
<tr>
<td>Path</td>
<td>[% string_title %]</td>
<td>[% the_base_link_to_the_resource %]</td>
</tr>
<tr>
<td>per_page</td>
<td>[% integer_title %]</td>
<td>[% the_number_of_models_per_page %]</td>
</tr>
<tr>
<td>to</td>
<td>[% integer_title %]</td>
<td>[% the_index_of_the_last_retrieved_item %]</td>
</tr>
<tr>
<td>total</td>
<td>[% integer_title %]</td>
<td>[% the_total_of_available_pages %]</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
[% include_failed_authentication_for_authorized_request %]
</div>
</div>
<div class="card mb-3" id="store-documentation">
<div class="card-header text-bg-success d-flex justify-content-between align-items-center p-3">
<div>
<span>POST</span>
<span><strong>/{{ Route::getRoutes()->getByName('[% store_route_name %]')->uri() }}</strong></span>
<p class="mb-0">[% store_route_description %]</p>
</div>
<div>
<button type="button" data-bs-toggle="collapse" data-bs-target="#store" aria-controls="store" class="btn btn-success btn-sm" aria-expanded="false">
<span class="fa-solid fa-chevron-down"></span>
</button>
</div>
</div>
<div class="card-body collapse" id="store">
<h3><strong>[% request_title %]</strong></h3>
@include('[% path_to_view_home %]fields-list', [
'withValidation' => true
])
<hr>
<h3><strong>[% response_title %]</strong></h3>
<p>[% store_route_response_description %]</p>
<p></p>
@include('[% path_to_view_home %]retrieved')
@include('[% path_to_view_home %]failed-to-retrieve')
@include('[% path_to_view_home %]failed-validation')
[% include_failed_authentication_for_authorized_request %]
</div>
</div>
<div class="card mb-3" id="update-documentation">
<div class="card-header text-bg-warning d-flex justify-content-between align-items-center p-3">
<div>
<span class="">POST</span>
<span><strong>/{{ Route::getRoutes()->getByName('[% update_route_name %]')->uri() }}</strong></span>
<p class="mb-0">[% update_route_description %]</p>
</div>
<div>
<button type="button" data-bs-toggle="collapse" data-bs-target="#update" aria-controls="update" class="btn btn-warning btn-sm" aria-expanded="false">
<span class="fa-solid fa-chevron-down"></span>
</button>
</div>
</div>
<div class="card-collapse collapse" id="update">
<div class="card-body">
<h3><strong>[% request_title %]</strong></h3>
@include('[% path_to_view_home %]fields-list', [
'withValidation' => true,
'withPathId' => true,
])
<hr>
<h3><strong>[% response_title %]</strong></h3>
<p>[% update_route_response_description %]</p>
<p></p>
@include('[% path_to_view_home %]retrieved')
@include('[% path_to_view_home %]failed-to-retrieve')
@include('[% path_to_view_home %]failed-validation')
[% include_failed_authentication_for_authorized_request %]
</div>
</div>
</div>
<div class="card mb-3" id="show-documentation">
<div class="card-header text-bg-info d-flex justify-content-between align-items-center p-3">
<div>
<span class="">GET</span>
<span><strong>/{{ Route::getRoutes()->getByName('[% show_route_name %]')->uri() }}</strong></span>
<p class="mb-0">[% show_route_description %]</p>
</div>
<div>
<button type="button" data-bs-toggle="collapse" data-bs-target="#show" aria-controls="show" class="btn btn-info btn-sm" aria-expanded="false">
<span class="fa-solid fa-chevron-down"></span>
</button>
</div>
</div>
<div class="card-body collapse" id="show">
<h3><strong>[% request_title %]</strong></h3>
<table class="table table-stripped">
<thead>
<tr>
<th class="col-md-2">[% parameter_name_title %]</th>
<th class="col-md-2">[% data_type_title %]</th>
<th class="col-md-2">[% parameter_type_title %]</th>
<th class="col-md-6">[% description_title %]</th>
</tr>
</thead>
<tbody>
[% include_parameter_for_authorized_request %]
<tr>
<td>[% model_name %]</td>
<td>[% integer_title %]</td>
<td><span class="label label-info" title="[% this_parameter_is_part_of_the_path %]">[% path_title %]</span></td>
<td>[% the_id_of_model_to_retrieve %]</td>
</tr>
</tbody>
</table>
<hr>
<h3><strong>[% response_title %]</strong></h3>
<p>[% show_route_response_description %] </p>
<p></p>
@include('[% path_to_view_home %]retrieved')
@include('[% path_to_view_home %]failed-to-retrieve')
[% include_failed_authentication_for_authorized_request %]
</div>
</div>
<div class="card card-danger mb-3" id="destroy-documentation">
<div class="card-header text-bg-danger d-flex justify-content-between align-items-center p-3">
<div>
<span class="">DELETE</span>
<span><strong>/{{ Route::getRoutes()->getByName('[% destroy_route_name %]')->uri() }}</strong></span>
<p class="mb-0">[% destroy_route_description %]</p>
</div>
<div>
<button type="button" data-bs-toggle="collapse" data-bs-target="#destroy" aria-controls="destroy" class="btn btn-danger btn-sm" aria-expanded="false">
<span class="fa-solid fa-chevron-down"></span>
</button>
</div>
</div>
<div class="card-body collapse" id="destroy">
<h3><strong>[% request_title %]</strong></h3>
<table class="table table-stripped">
<thead>
<tr>
<th class="col-md-2">[% parameter_name_title %]</th>
<th class="col-md-2">[% data_type_title %]</th>
<th class="col-md-2">[% parameter_type_title %]</th>
<th class="col-md-6">[% description_title %]</th>
</tr>
</thead>
<tbody>
[% include_parameter_for_authorized_request %]
<tr>
<td>[% model_name %]</td>
<td>[% integer_title %]</td>
<td><span class="label label-info" title="[% this_parameter_is_part_of_the_path %]">[% path_title %]</span></td>
<td>[% the_id_of_model_to_delete %]</td>
</tr>
</tbody>
</table>
<hr>
<h3><strong>[% response_title %]</strong></h3>
<p>[% destroy_route_response_description %]</p>
<p></p>
@include('[% path_to_view_home %]retrieved')
@include('[% path_to_view_home %]failed-to-retrieve')
[% include_failed_authentication_for_authorized_request %]
</div>
</div>
<hr>
<h2>[% model_definition_title %]</h2>
<div class="card" id="[% model_name %]-model-documentation">
<div class="card-header text-bg-secondary d-flex justify-content-between align-items-center p-3">
<div>
<span class="">[% model_name_title %]</span>
</div>
<div>
<button type="button" data-bs-toggle="collapse" data-bs-target="#model-definitions" aria-controls="model-definitions" class="btn btn-secondary btn-sm" aria-expanded="false">
<span class="fa-solid fa-chevron-down"></span>
</button>
</div>
</div>
<div class="card-body collapse" id="model-definitions">
<table class="table table-stripped">
<thead>
<tr>
<th>[% field_name_title %]</th>
<th>[% field_type_title %]</th>
<th>[% description_title %]</th>
</tr>
</thead>
<tbody>
[% fields_list_for_body %]
</tbody>
</table>
</div>
</div>
@endsection

View File

@@ -1,2 +0,0 @@
Route::get('[% prefix %][% version %]', [[% controller_name %]::class, 'index'])
->name('[% index_route_name %]');

View File

@@ -1,2 +0,0 @@
Route::get('[% prefix %][% version %]', '[% controller_name %]@index')
->name('[% index_route_name %]');

View File

@@ -1,38 +0,0 @@
<?php
namespace [% namespace %];
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
/**
* Valid versions
*
* @var array
*/
private $versions = [
'[% api_version_number %]',
];
/**
* Get a valid version from the available list.
*
* @param string $version
*
* @return string
*/
protected function getVersion($version)
{
if (in_array($version, $this->versions)) {
return $version;
}
return end($this->versions);
}
}

View File

@@ -1,50 +0,0 @@
<?php
namespace [% namespace %];
use Illuminate\Http\Resources\Json\ResourceCollection;
use [% use_full_model_name %];
class [% api_resource_collection_class %] extends ResourceCollection
{
/**
* The response message
*
* @var mixed
*/
protected $message;
/**
* Create a new resource instance.
*
* @param mixed $resource
* @param mixed $message
*
* @return void
*/
public function __construct($resource, $message = null)
{
parent::__construct($resource);
$this->message = $message;
}
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
{
return [
'data' => $this->collection->transform(function ($[% model_name_singular_variable %]) {
return $this->transformModel($[% model_name_singular_variable %]);
}),
'message' => $this->message,
'success' => true,
];
}
[% transform_method %]
}

View File

@@ -1,59 +0,0 @@
<?php
namespace [% namespace %];
use Illuminate\Http\Resources\Json\Resource;
class [% api_resource_class %] extends Resource
{
/**
* The response message
*
* @var mixed
*/
protected $message;
/**
* Create a new resource instance.
*
* @param mixed $resource
* @param mixed $message
*
* @return void
*/
public function __construct($resource, $message = null)
{
parent::__construct($resource);
$this->message = $message;
}
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
*
* @return array
*/
public function toArray($request)
{
return [
[% model_api_array %]
];
}
/**
* Get any additional data that should be returned with the resource array.
*
* @param \Illuminate\Http\Request $request
*
* @return array
*/
public function with($request)
{
return [
'success' => true,
'message' => $this->message,
];
}
}

View File

@@ -1,10 +0,0 @@
Route::get('/', [[% controller_name %]::class, 'index'])
->name('[% index_route_name %]');
Route::get('/show/{[% model_name_singular_variable %]}',[[% controller_name %]::class, 'show'])
->name('[% show_route_name %]')[% route_id_clause %];
Route::post('/', [[% controller_name %]::class, 'store'])
->name('[% store_route_name %]');
Route::put('[% model_name_snake %]/{[% model_name_singular_variable %]}', [[% controller_name %]::class, 'update'])
->name('[% update_route_name %]')[% route_id_clause %];
Route::delete('/[% model_name_snake %]/{[% model_name_singular_variable %]}',[[% controller_name %]::class, 'destroy'])
->name('[% destroy_route_name %]')[% route_id_clause %];

View File

@@ -1,10 +0,0 @@
Route::get('/', '[% controller_name %]@index')
->name('[% index_route_name %]');
Route::get('/show/{[% model_name_singular_variable %]}','[% controller_name %]@show')
->name('[% show_route_name %]')[% route_id_clause %];
Route::post('/', '[% controller_name %]@store')
->name('[% store_route_name %]');
Route::put('[% model_name_snake %]/{[% model_name_singular_variable %]}', '[% controller_name %]@update')
->name('[% update_route_name %]')[% route_id_clause %];
Route::delete('/[% model_name_snake %]/{[% model_name_singular_variable %]}','[% controller_name %]@destroy')
->name('[% destroy_route_name %]')[% route_id_clause %];

View File

@@ -1,17 +0,0 @@
/**
* Validate the given request with the defined rules.
*
* @param [% request_fullname %] $request
*
* @return boolean
*/
protected function affirm(Request $request)
{
$rules = [
[% validation_rules %]
];
[% file_validation_snippet %]
return $this->validate($request, $rules);
}

View File

@@ -1,10 +0,0 @@
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
[% auth_middleware %]
}

View File

@@ -1,21 +0,0 @@
/**
* Get the request's data from the request.
*
* [% request_name_comment %]
* @return array
*/
[% visibility_level %] function getData([% type_hinted_request_name %])
{
$rules = [
[% validation_rules %]
];
[% file_validation_snippet %]
$data = [% request_variable %]->validate($rules);
[% file_snippet %]
[% boolean_snippet %]
[% string_to_null_snippet %]
return $data;
}

View File

@@ -1,15 +0,0 @@
/**
* Get the request's data from the request.
*
* [% request_name_comment %]
* @return array
*/
[% visibility_level %] function getData([% type_hinted_request_name %])
{
$data = [% request_variable %]->only([% fillable %]);
[% file_snippet %]
[% boolean_snippet %]
[% string_to_null_snippet %]
return $data;
}

View File

@@ -1,19 +0,0 @@
/**
* Moves the attached file to the server.
*
* @param \Symfony\Component\HttpFoundation\File\UploadedFile $file
*
* @return string
*/
protected function moveFile($file)
{
if (!$file->isValid()) {
return '';
}
$path = config('laravel-code-generator.files_upload_path', 'uploads');
$saved = $file->store('public/' . $path, config('filesystems.default'));
return substr($saved, 7);
}

View File

@@ -1,20 +0,0 @@
/**
* Moves the attached file to the server.
*
* @param \Symfony\Component\HttpFoundation\File\UploadedFile $file
*
* @return string
*/
protected function moveFile($file)
{
if (!$file->isValid()) {
return '';
}
$fileName = sprintf('%s.%s', uniqid(), $file->getClientOriginalExtension());
$destinationPath = config('laravel-code-generator.files_upload_path','uploads');
$path = $file->move($destinationPath, $fileName);
return $destinationPath . '/' . $fileName;
}

View File

@@ -1,126 +0,0 @@
<?php
namespace [% namespace %];
[% use_command_placeholder %]
use Exception;
class [% controller_name %] [% controller_extends %]
{
[% constructor %]
/**
* Display a listing of the [% model_name_plural %].
*
* @return \Illuminate\View\View
*/
public function index()
{
$[% model_name_plural_variable %] = [% model_name_class %]::[% with_relations_for_index %]paginate([% models_per_page %]);
return view('[% index_view_name %]'[% view_variables_for_index %]);
}
/**
* Show the form for creating a new [% model_name %].
*
* @return \Illuminate\View\View
*/
public function create()
{
[% relation_collections %]
return view('[% create_view_name %]'[% view_variables_for_create %]);
}
/**
* Store a new [% model_name %] in the storage.
*
* @param [% request_fullname %] [% request_variable %]
*
* @return \Illuminate\Http\RedirectResponse | \Illuminate\Routing\Redirector
*/
public function store([% type_hinted_request_name %])
{
[% call_affirm %]
$[% data_variable %] = [% call_get_data %];
[% on_store_setter %]
[% model_name_class %]::create($[% data_variable %]);
return redirect()->route('[% index_route_name %]')
->with('success_message', [% model_was_added %]);
}
/**
* Display the specified [% model_name %].
*
* @param int $id
*
* @return \Illuminate\View\View
*/
public function show($id)
{
$[% model_name_singular_variable %] = [% model_name_class %]::[% with_relations_for_show %]findOrFail($id);
return view('[% show_view_name %]'[% view_variables_for_show %]);
}
/**
* Show the form for editing the specified [% model_name %].
*
* @param int $id
*
* @return \Illuminate\View\View
*/
public function edit($id)
{
$[% model_name_singular_variable %] = [% model_name_class %]::findOrFail($id);
[% relation_collections %]
return view('[% edit_view_name %]'[% view_variables_for_edit %]);
}
/**
* Update the specified [% model_name %] in the storage.
*
* @param int $id
* @param [% request_fullname %] [% request_variable %]
*
* @return \Illuminate\Http\RedirectResponse | \Illuminate\Routing\Redirector
*/
public function update($id, [% type_hinted_request_name %])
{
[% call_affirm %]
$[% data_variable %] = [% call_get_data %];
[% on_update_setter %]
$[% model_name_singular_variable %] = [% model_name_class %]::findOrFail($id);
$[% model_name_singular_variable %]->update($[% data_variable %]);
return redirect()->route('[% index_route_name %]')
->with('success_message', [% model_was_updated %]);
}
/**
* Remove the specified [% model_name %] from the storage.
*
* @param int $id
*
* @return \Illuminate\Http\RedirectResponse | \Illuminate\Routing\Redirector
*/
public function destroy($id)
{
try {
$[% model_name_singular_variable %] = [% model_name_class %]::findOrFail($id);
$[% model_name_singular_variable %]->delete();
return redirect()->route('[% index_route_name %]')
->with('success_message', [% model_was_deleted %]);
} catch (Exception $exception) {
return back()->withInput()
->withErrors(['unexpected_error' => [% unexpected_error %]]);
}
}
[% affirm_method %]
[% get_data_method %]
[% upload_method %]
}

View File

@@ -1,46 +0,0 @@
@extends('[% layout_name %]')
@section('content')
<div class="card text-bg-theme">
<div class="card-header d-flex justify-content-between align-items-center p-3">
<h4 class="m-0">[% create_model %]</h4>
<div>
<a href="{{ route('[% index_route_name %]') }}" class="btn btn-primary" title="[% show_all_models %]">
<span class="fa-solid fa-table-list" aria-hidden="true"></span>
</a>
</div>
</div>
<div class="card-body">
@if ($errors->any())
<div class="alert alert-danger" role="alert">
<ul class="list-unstyled mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="POST" class="needs-validation" novalidate action="{{ route('[% store_route_name %]') }}" accept-charset="UTF-8" id="[% form_id %]" name="[% form_name %]" [% upload_files %]>
{{ csrf_field() }}
@include ('[% form_view_name %]', [
'[% model_name_singular_variable %]' => null,
])
<div class="col-lg-10 col-xl-9 offset-lg-2 offset-xl-3">
<input class="btn btn-primary" type="submit" value="[% add %]">
</div>
</form>
</div>
</div>
@endsection

View File

@@ -1,47 +0,0 @@
@extends('[% layout_name %]')
@section('content')
<div class="card text-bg-theme">
<div class="card-header d-flex justify-content-between align-items-center p-3">
<h4 class="m-0">{{ !empty([% model_header %]) ? [% model_header %] : '[% model_name_title %]' }}</h4>
<div>
<a href="{{ route('[% index_route_name %]') }}" class="btn btn-primary" title="[% show_all_models %]">
<span class="fa-solid fa-table-list" aria-hidden="true"></span>
</a>
<a href="{{ route('[% create_route_name %]') }}" class="btn btn-secondary" title="[% create_model %]">
<span class="fa-solid fa-plus" aria-hidden="true"></span>
</a>
</div>
</div>
<div class="card-body">
@if ($errors->any())
<div class="alert alert-danger" role="alert">
<ul class="list-unstyled mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="POST" class="needs-validation" novalidate action="{{ route('[% update_route_name %]', $[% model_name_singular_variable %]->[% primary_key %]) }}" id="[% form_id %]" name="[% form_name %]" accept-charset="UTF-8" [% upload_files %]>
{{ csrf_field() }}
<input name="_method" type="hidden" value="PUT">
@include ('[% form_view_name %]', [
'[% model_name_singular_variable %]' => $[% model_name_singular_variable %],
])
<div class="col-lg-10 col-xl-9 offset-lg-2 offset-xl-3">
<input class="btn btn-primary" type="submit" value="[% update %]">
</div>
</form>
</div>
</div>
@endsection

View File

@@ -1,14 +0,0 @@
<div class="mb-3">
<input class="form-control{{ $errors->has('[% field_name %]') ? ' is-invalid' : '' }}" type="file" name="[% field_name %]" id="[% field_name %]" class="[% css_class %]">
</div>
@if (isset($[% model_name_singular_variable %]->[% field_name %]) && !empty($[% model_name_singular_variable %]->[% field_name %]))
<div class="input-group mb-3">
<div class="form-check">
<input type="checkbox" name="custom_delete_[% field_name %]" id="custom_delete_[% field_name %]" class="form-check-input custom-delete-file" value="1" {{ old('custom_delete_[% field_name %]', '0') == '1' ? 'checked' : '' }}>
</div>
<label class="form-check-label" for="custom_delete_[% field_name %]"> Delete {{ [% field_value %] }}</label>
</div>
@endif

View File

@@ -1 +0,0 @@
{!! $errors->first('[% field_name %]', '<div class="invalid-feedback">:message</div>') !!}

View File

@@ -1 +0,0 @@
<input class="form-control{{ $errors->has('[% field_name %]') ? ' is-invalid' : '' }}[% css_class %]" name="[% field_name %]" type="[% field_type %]" id="[% field_name %]" value="[% field_value %]"[% min_length %][% max_length %][% min_value %][% max_value %][% required_field %][% placeholder %][% step %]>

View File

@@ -1,8 +0,0 @@
<div class="mb-3 row">
[% field_label %]
<div class="col-lg-10 col-xl-9">
[% field_input %]
[% field_validation_helper %]
</div>
</div>

View File

@@ -1 +0,0 @@
<label for="[% field_name %]" class="col-form-label text-lg-end col-lg-2 col-xl-3">[% field_title %]</label>

View File

@@ -1,8 +0,0 @@
<select class="form-select{{ $errors->has('[% field_name %]') ? ' is-invalid' : '' }}[% css_class %]" id="[% field_name %]" name="[% field_name %]">
[% placeholder %]
@foreach (range(1, 12) as $value)
<option value="{{ $value }}"[% selected_value %]>
{{ date('F', mktime(0, 0, 0, $value, 1)) }}
</option>
@endforeach
</select>

View File

@@ -1 +0,0 @@
<div class="col-form-label text-lg-end col-lg-2 col-xl-3"></div>

View File

@@ -1 +0,0 @@
<input class="form-control{{ $errors->has('[% field_name %]') ? ' is-invalid' : '' }}[% css_class %]" name="[% field_name %]" type="password" id="[% field_name %]" value="[% field_value %]"[% min_length %][% max_length %][% min_value %][% max_value %][% required_field %][% placeholder %]>

View File

@@ -1,6 +0,0 @@
<div class="form-check [% field_type %]">
<input id="[% item_id %]" class="form-check-input[% required_class %][% css_class %]" name="[% field_name %]" type="[% field_type %]" value="[% option_value %]"[% required_field %][% checked_item %]>
<label class="form-check-label" for="[% item_id %]">
[% item_title %]
</label>
</div>

View File

@@ -1,6 +0,0 @@
<div class="form-check form-check-inline[% field_type %]">
<input id="[% item_id %]" class="form-check-input[% required_class %][% css_class %]" name="[% field_name %]" type="[% field_type %]" value="[% option_value %]"[% required_field %][% checked_item %]>
<label class="form-check-label" for="[% item_id %]">
[% item_title %]
</label>
</div>

View File

@@ -1,35 +0,0 @@
<?php
namespace [% class_namespace %];
use Illuminate\Foundation\Http\FormRequest;
[% use_command_placeholder %]
class [% form_request_class %] extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return [% autherized_boolean %];
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$rules = [
[% validation_rules %]
];
[% file_validation_snippet %]
return $rules;
}
[% get_data_method %]
[% upload_method %]
}

View File

@@ -1,9 +0,0 @@
<select class="form-select{{ $errors->has('[% field_name %]') ? ' is-invalid' : '' }}[% css_class %]" id="[% field_name %]" name="[% field_name %]"[% field_multiple %][% required_field %]>
[% placeholder %]
@foreach ([% field_items %] as $key => [% field_item %])
<option value="{{ $key }}"[% selected_value %]>
{{ [% field_item %] }}
</option>
@endforeach
</select>

View File

@@ -1,9 +0,0 @@
<select class="form-select{{ $errors->has('[% field_name %]') ? ' is-invalid' : '' }}[% css_class %]" id="[% field_name %]" name="[% field_name %]">
[% placeholder %]
@foreach (range([% min_value %], [% max_value %]) as $value)
<option value="{{ $value }}"[% selected_value %]>
{{ $value }}
</option>
@endforeach
</select>

View File

@@ -1 +0,0 @@
<textarea class="form-control{{ $errors->has('[% field_name %]') ? ' is-invalid' : '' }}[% css_class %]" name="[% field_name %]" id="[% field_name %]"[% min_length %][% max_length %][% min_value %][% max_value %][% required_field %][% placeholder %]>[% field_value %]</textarea>

View File

@@ -1 +0,0 @@
[% form_fields_html %]

View File

@@ -1,78 +0,0 @@
@extends('[% layout_name %]')
@section('content')
@if(Session::has('success_message'))
<div class="alert alert-success alert-dismissible" role="alert">
{!! session('success_message') !!}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
@endif
<div class="card text-bg-theme">
<div class="card-header d-flex justify-content-between align-items-center p-3">
<h4 class="m-0">[% model_name_plural_title %]</h4>
<div>
<a href="{{ route('[% create_route_name %]') }}" class="btn btn-secondary" title="[% create_model %]">
<span class="fa-solid fa-plus" aria-hidden="true"></span>
</a>
</div>
</div>
@if(count($[% model_name_plural_variable %]) == 0)
<div class="card-body text-center">
<h4>[% no_models_available %]</h4>
</div>
@else
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-striped ">
<thead>
<tr>
[% header_cells %]
<th></th>
</tr>
</thead>
<tbody>
@foreach($[% model_name_plural_variable %] as $[% model_name_singular_variable %])
<tr>
[% body_cells %]
<td class="text-end">
<form method="POST" action="{!! route('[% destroy_route_name %]', $[% model_name_singular_variable %]->[% primary_key %]) !!}" accept-charset="UTF-8">
<input name="_method" value="DELETE" type="hidden">
{{ csrf_field() }}
<div class="btn-group btn-group-sm" role="group">
<a href="{{ route('[% show_route_name %]', $[% model_name_singular_variable %]->[% primary_key %] ) }}" class="btn btn-info" title="[% show_model %]">
<span class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></span>
</a>
<a href="{{ route('[% edit_route_name %]', $[% model_name_singular_variable %]->[% primary_key %] ) }}" class="btn btn-primary" title="[% edit_model %]">
<span class="fa-regular fa-pen-to-square" aria-hidden="true"></span>
</a>
<button type="submit" class="btn btn-danger" title="[% delete_model %]" onclick="return confirm(&quot;[% confirm_delete %]&quot;)">
<span class="fa-regular fa-trash-can" aria-hidden="true"></span>
</button>
</div>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
{!! $[% model_name_plural_variable %]->links('[% pagination_view_name %]') !!}
</div>
@endif
</div>
@endsection

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