diff --git a/.env.example b/.env.example deleted file mode 100644 index 7b49625..0000000 --- a/.env.example +++ /dev/null @@ -1,64 +0,0 @@ -APP_NAME=Laravel -APP_ENV=local -APP_KEY= -APP_DEBUG=true -APP_TIMEZONE=UTC -APP_URL=http://localhost - -APP_LOCALE=en -APP_FALLBACK_LOCALE=en -APP_FAKER_LOCALE=en_US - -APP_MAINTENANCE_DRIVER=file -APP_MAINTENANCE_STORE=database - -BCRYPT_ROUNDS=12 - -LOG_CHANNEL=stack -LOG_STACK=single -LOG_DEPRECATIONS_CHANNEL=null -LOG_LEVEL=debug - -DB_CONNECTION=sqlite -# DB_HOST=127.0.0.1 -# DB_PORT=3306 -# DB_DATABASE=laravel -# DB_USERNAME=root -# DB_PASSWORD= - -SESSION_DRIVER=database -SESSION_LIFETIME=120 -SESSION_ENCRYPT=false -SESSION_PATH=/ -SESSION_DOMAIN=null - -BROADCAST_CONNECTION=log -FILESYSTEM_DISK=local -QUEUE_CONNECTION=database - -CACHE_STORE=database -CACHE_PREFIX= - -MEMCACHED_HOST=127.0.0.1 - -REDIS_CLIENT=phpredis -REDIS_HOST=127.0.0.1 -REDIS_PASSWORD=null -REDIS_PORT=6379 - -MAIL_MAILER=log -MAIL_HOST=127.0.0.1 -MAIL_PORT=2525 -MAIL_USERNAME=null -MAIL_PASSWORD=null -MAIL_ENCRYPTION=null -MAIL_FROM_ADDRESS="hello@example.com" -MAIL_FROM_NAME="${APP_NAME}" - -AWS_ACCESS_KEY_ID= -AWS_SECRET_ACCESS_KEY= -AWS_DEFAULT_REGION=us-east-1 -AWS_BUCKET= -AWS_USE_PATH_STYLE_ENDPOINT=false - -VITE_APP_NAME="${APP_NAME}" diff --git a/app/Http/Controllers/JenisKegiatanController.php b/app/Http/Controllers/JenisKegiatanController.php index 342acbe..5d08841 100644 --- a/app/Http/Controllers/JenisKegiatanController.php +++ b/app/Http/Controllers/JenisKegiatanController.php @@ -63,4 +63,17 @@ class JenisKegiatanController extends Controller return back()->with('error', 'Something went wrong.'); } } + + public function getAll() + { + try { + $jeniskegiatan = JenisKegiatan::where('IsPublish', true) + ->select('JenisKegiatanId', 'NamaJenisKegiatan') + ->get(); + return response()->json($jeniskegiatan); + } catch (\Exception $e) { + Log::error('Error fetching all Jenis Kegiatan: ' . $e->getMessage()); + return response()->json(['error' => 'Something went wrong'], 500); + } + } } diff --git a/app/Http/Controllers/PelaporanALController.php b/app/Http/Controllers/PelaporanALController.php new file mode 100644 index 0000000..e5136c2 --- /dev/null +++ b/app/Http/Controllers/PelaporanALController.php @@ -0,0 +1,20 @@ +getMessage()); + return back()->with('error', 'Something went wrong.'); + } + } +} diff --git a/app/Http/Controllers/PerusahaanController.php b/app/Http/Controllers/PerusahaanController.php new file mode 100644 index 0000000..3ddf044 --- /dev/null +++ b/app/Http/Controllers/PerusahaanController.php @@ -0,0 +1,178 @@ +get(); + return Inertia::render('admin/perusahaan/index_perusahaan', [ + 'perusahaan' => $perusahaan, + 'jenisKegiatan' => JenisKegiatan::all(), + 'jenisDokIL' => JenisDokIL::all(), + 'verifikator' => Verifikator::all(), + 'kabupaten' => Kabupaten::all(), + 'kecamatan' => Kecamatan::all(), + 'kelurahan' => Kelurahan::all(), + ]); + + } catch (\Exception $e) { + Log::error('Error fetching data: ' . $e->getMessage()); + return back()->with('error', 'Terjadi kesalahan saat memuat data.'); + } + } + + // public function store(Request $request) + // { + // $request->validate([ + // 'ILDokumen' => 'required|file|mimes:pdf|max:20480', + // ]); + + // try { + // return DB::transaction(function () use ($request) { + // if ($request->hasFile('ILDokumen')) { + // $file = $request->file('ILDokumen'); + // $fileName = time() . '_' . $file->getClientOriginalName(); + + // if (!Storage::exists('public/files/il')) { + // Storage::makeDirectory('public/files/il'); + // } + + // $path = $file->storeAs('files/il', $fileName, 'public'); + + // $request->merge(['ILDokumen' => $path]); + // } + + // $perusahaan = Perusahaan::create($request->all()); + + // return response()->json([ + // 'message' => 'Perusahaan berhasil ditambahkan', + // 'data' => $perusahaan + // ]); + // }); + // } catch (\Exception $e) { + // if (isset($path) && Storage::exists($path)) { + // Storage::delete($path); + // } + + // return response()->json([ + // 'message' => 'Error: ' . $e->getMessage() + // ], 500); + // } + // } + + public function store(Request $request) +{ + $request->validate([ + 'NomorInduk' => 'required|string|unique:Perusahaan', + 'NamaPerusahaan' => 'required|string', + 'JenisKegiatanId' => 'required|string', + 'VerifikatorId' => 'required|string', + 'KelurahanId' => 'required|string', + 'Email' => 'required|email', + ]); + + try { + DB::beginTransaction(); + + $data = $request->all(); + + if ($request->hasFile('ILDokumen')) { + $file = $request->file('ILDokumen'); + + if (!$file->isValid()) { + throw new \Exception('Invalid PDF file'); + } + + $fileName = time() . '_' . $file->getClientOriginalName(); + $path = $file->storeAs('files/il', $fileName, 'public'); + + if ($path === false) { + throw new \Exception('Failed to store PDF file'); + } + + $data['ILDokumen'] = $path; + } + + // Convert boolean string to actual boolean + $data['IsPublish'] = filter_var($request->input('IsPublish'), FILTER_VALIDATE_BOOLEAN); + $data['ReportLocked'] = filter_var($request->input('ReportLocked'), FILTER_VALIDATE_BOOLEAN); + + $perusahaan = Perusahaan::create($data); + + DB::commit(); + + return redirect() + ->route('admin.perusahaan.index') + ->with('success', 'Perusahaan berhasil ditambahkan'); + + } catch (\Exception $e) { + DB::rollBack(); + + if (isset($path) && Storage::disk('public')->exists($path)) { + Storage::disk('public')->delete($path); + } + + Log::error('Error creating perusahaan: ' . $e->getMessage()); + + return response()->json([ + 'message' => 'Error: ' . $e->getMessage() + ], 500); + } +} + + public function show(Perusahaan $perusahaan): JsonResponse + { + $perusahaan->load([ + 'JenisKegiatan', + 'Kelurahan', + 'JenisDokIL', + 'Verifikator', + 'Kawasan' + ]); + + return response()->json([ + 'status' => 'success', + 'data' => $perusahaan + ]); + } + + public function update(PerusahaanRequest $request, Perusahaan $perusahaan): JsonResponse + { + $perusahaan->update($request->validated()); + + return response()->json([ + 'status' => 'success', + 'message' => 'Data perusahaan berhasil diperbarui', + 'data' => $perusahaan + ]); + } + + public function destroy(Perusahaan $perusahaan): JsonResponse + { + $perusahaan->delete(); + + return response()->json([ + 'status' => 'success', + 'message' => 'Data perusahaan berhasil dihapus' + ]); + } +} diff --git a/app/Http/Controllers/PostController.php b/app/Http/Controllers/PostController.php index 12836cb..d61358c 100644 --- a/app/Http/Controllers/PostController.php +++ b/app/Http/Controllers/PostController.php @@ -95,41 +95,52 @@ class PostController extends Controller public function edit(Post $post) { + // Debug the image path + Log::info('Image path:', ['path' => $post->ImagePost]); + return Inertia::render('admin/post/edit_post', [ - 'post' => $post, + 'posting' => [ + ...$post->toArray(), + 'ImagePost' => $post->ImagePost ? '/storage/' . $post->ImagePost : null, + ], 'kategori' => Kategori::all(), - 'subkategori' => SubKategori::where('KategoriId', $post->KategoriId)->get(), + 'subkategori' => SubKategori::all(), + 'existingPosts' => Post::where('PostId', '!=', $post->PostId) + ->select('JudulPost', 'KategoriId') + ->get() ]); } public function update(PostRequest $request, Post $post) { try { - $data = array_filter($request->validated(), function($value) { - return $value !== null; - }); + DB::beginTransaction(); + $data = $request->validated(); + // Only update image if new one is uploaded if ($request->hasFile('ImagePost')) { + // Delete old image if exists if ($post->ImagePost && Storage::disk('public')->exists($post->ImagePost)) { Storage::disk('public')->delete($post->ImagePost); } $data['ImagePost'] = $request->file('ImagePost')->store('images/posts', 'public'); + } else { + // Keep existing image if no new one uploaded + unset($data['ImagePost']); } - if (isset($data['IsPublish'])) { - $data['IsPublish'] = (bool) $data['IsPublish']; - } - + $data['IsPublish'] = $request->boolean('IsPublish'); $post->update($data); - return redirect() - ->route('admin.post.index') - ->with('success', 'Post berhasil diperbarui.'); + DB::commit(); + return redirect()->route('admin.post.index')->with('success', 'Post berhasil diperbarui.'); } catch (\Exception $e) { + DB::rollBack(); Log::error('Error updating Post: ' . $e->getMessage()); return back()->with('error', 'Terjadi kesalahan saat memperbarui post.'); } + } public function destroy(Post $post) diff --git a/app/Http/Requests/JenisDokILRequest.php b/app/Http/Requests/JenisDokILRequest.php index 5579d95..3b81876 100644 --- a/app/Http/Requests/JenisDokILRequest.php +++ b/app/Http/Requests/JenisDokILRequest.php @@ -23,7 +23,6 @@ class JenisDokILRequest extends FormRequest { return [ 'NamaJenisDokIL' => 'required|string|max:255', - 'KodeJenisDokIL' => 'required|string|max:20', ]; } } diff --git a/app/Http/Requests/PerusahaanRequest.php b/app/Http/Requests/PerusahaanRequest.php new file mode 100644 index 0000000..ed0f795 --- /dev/null +++ b/app/Http/Requests/PerusahaanRequest.php @@ -0,0 +1,47 @@ +|string> + */ + public function rules(): array + { + return [ + 'NomorInduk' => ['string'], + 'JenisKegiatanId' => ['required', 'integer'], + 'NamaPerusahaan' => ['required', 'string'], + 'Alamat' => ['string'], + 'KelurahanId' => ['required', 'integer'], + 'KodePos' => ['string'], + 'Telepon' => ['string'], + 'Fax' => ['string'], + 'Email' => ['required', 'string'], + 'Lintang' => ['string'], + 'Bujur' => ['string'], + 'CPNama' => ['string'], + 'CPTelepon' => ['string'], + 'ILNomor' => ['string'], + 'ILTanggal' => ['string'], + 'JenisDokILId' => ['integer'], + 'VerifikatorId' => ['required', 'integer'], + 'IsPublish' => ['required', 'boolean'], + 'ILDokumen' => ['string'], + 'Kawasan' => ['string'], + ]; + } +} diff --git a/app/Models/JenisDokIL.php b/app/Models/JenisDokIL.php index da7bebd..b7bcbea 100644 --- a/app/Models/JenisDokIL.php +++ b/app/Models/JenisDokIL.php @@ -9,7 +9,6 @@ class JenisDokIL extends Model protected $table = 'JenisDokIL'; protected $primaryKey = 'JenisDokILId'; protected $fillable = [ - 'KodeJenisDokIL', 'NamaJenisDokIL' ]; } diff --git a/app/Models/JenisKegiatan.php b/app/Models/JenisKegiatan.php index 1d60dd4..24c6f07 100644 --- a/app/Models/JenisKegiatan.php +++ b/app/Models/JenisKegiatan.php @@ -21,4 +21,9 @@ class JenisKegiatan extends Model 'IsPublish', ]; + public function Perusahaan() + { + return $this->hasMany(Perusahaan::class, 'JenisKegiatanId'); + } + } diff --git a/app/Models/Perusahaan.php b/app/Models/Perusahaan.php index 0fbcc96..1da21e3 100644 --- a/app/Models/Perusahaan.php +++ b/app/Models/Perusahaan.php @@ -2,16 +2,20 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\SoftDeletes; class Perusahaan extends Model { + use HasFactory; protected $table = 'Perusahaan'; protected $primaryKey = 'PerusahaanId'; + protected $fillable = [ - 'NomorInduk', + 'NomorInduk', 'JenisKegiatanId', 'NamaPerusahaan', 'Alamat', @@ -28,57 +32,67 @@ class Perusahaan extends Model 'ILTanggal', 'JenisDokILId', 'VerifikatorId', - 'ReportLocked', 'IsPublish', 'ILDokumen', - 'ILPdlNomor', - 'ILPdlJenis', - 'DocPdlOrig', - 'DocPdlHash', - 'DocPdlPath', - 'ILPdlTanggal', - 'Kawasan' + 'ReportLocked' ]; protected $casts = [ 'ReportLocked' => 'boolean', 'IsPublish' => 'boolean', - 'ILPdlTanggal' => 'date', + 'JenisKegiatanId' => 'integer', + 'VerifikatorId' => 'integer', + 'KelurahanId' => 'integer', ]; - // Relationship with JenisKegiatan - public function jenisKegiatan(): BelongsTo + public function jenisKegiatan() { return $this->belongsTo(JenisKegiatan::class, 'JenisKegiatanId', 'JenisKegiatanId'); } - // Relationship with Kelurahan - public function kelurahan(): BelongsTo + protected $with = ['JenisKegiatan', 'Kelurahan']; + + public function kelurahan() { return $this->belongsTo(Kelurahan::class, 'KelurahanId', 'KelurahanId'); } + + public function kecamatan() + { + return $this->hasOneThrough( + Kecamatan::class, + Kelurahan::class, + 'KelurahanId', // Foreign key di tabel Kelurahan + 'KecamatanId', // Foreign key di tabel Kecamatan + 'KelurahanId', // Foreign key di tabel Perusahaan + 'KecamatanId' // Foreign key di tabel Kelurahan + ); + } + + public function kabupaten() + { + return $this->hasOneThrough( + Kabupaten::class, + Kecamatan::class, + 'KecamatanId', // Foreign key di tabel Kecamatan + 'KabupatenId', // Foreign key di tabel Kabupaten + 'KelurahanId', // Foreign key di tabel Perusahaan + 'KabupatenId' // Foreign key di tabel Kecamatan + ); + } + + public function verifikator() + { + return $this->belongsTo(Verifikator::class, 'VerifikatorId'); + } // Relationship with JenisDokIL - public function jenisDokIL(): BelongsTo + public function jenisDokIL() { return $this->belongsTo(JenisDokIL::class, 'JenisDokILId', 'JenisDokILId'); } - // Relationship with JenisDokIL for PDL - public function jenisDokILPdl(): BelongsTo - { - return $this->belongsTo(JenisDokIL::class, 'ILPdlJenis', 'JenisDokILId'); - } - // Relationship with Verifikator - public function verifikator(): BelongsTo - { - return $this->belongsTo(Verifikator::class, 'VerifikatorId', 'VerifikatorId'); - } - // Self-referential relationship for Kawasan - public function kawasan(): BelongsTo - { - return $this->belongsTo(Perusahaan::class, 'Kawasan', 'PerusahaanId'); - } + } diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php index 05fb5d9..a517b41 100644 --- a/database/migrations/0001_01_01_000000_create_users_table.php +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -14,6 +14,7 @@ return new class extends Migration Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); + $table->string('username')->unique(); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); diff --git a/database/migrations/2025_02_11_164124_create_kategori_table.php b/database/migrations/2025_02_11_164124_create_kategori_table.php index b95f5a9..c098d7a 100644 --- a/database/migrations/2025_02_11_164124_create_kategori_table.php +++ b/database/migrations/2025_02_11_164124_create_kategori_table.php @@ -13,7 +13,7 @@ return new class extends Migration { Schema::create('Kategori', function (Blueprint $table) { $table->id('KategoriId'); - $table->string('NamaKategori')->unique(); + $table->string('NamaKategori'); $table->softDeletes(); $table->timestamps(); }); diff --git a/database/migrations/2025_02_11_180031_add_username_to_users_table.php b/database/migrations/2025_02_11_180031_add_username_to_users_table.php deleted file mode 100644 index c17dac0..0000000 --- a/database/migrations/2025_02_11_180031_add_username_to_users_table.php +++ /dev/null @@ -1,28 +0,0 @@ -string('username')->unique()->after('name'); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::table('users', function (Blueprint $table) { - $table->dropColumn('username'); - }); - } -}; diff --git a/database/migrations/2025_02_12_003736_create_posts_table.php b/database/migrations/2025_02_12_003736_create_posts_table.php index 457a1ff..dde5543 100644 --- a/database/migrations/2025_02_12_003736_create_posts_table.php +++ b/database/migrations/2025_02_12_003736_create_posts_table.php @@ -19,6 +19,7 @@ return new class extends Migration $table->string('SlugPost'); $table->text('DescPost'); $table->string('ImagePost')->nullable(); + $table->boolean('IsPublish')->default(1); $table->timestamps(); diff --git a/database/migrations/2025_02_12_081712_add_is_publish_to_posts_table.php b/database/migrations/2025_02_12_081712_add_is_publish_to_posts_table.php deleted file mode 100644 index 2928c49..0000000 --- a/database/migrations/2025_02_12_081712_add_is_publish_to_posts_table.php +++ /dev/null @@ -1,29 +0,0 @@ -boolean('IsPublish')->default(0); - - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::table('Post', function (Blueprint $table) { - $table->dropColumn('IsPublish'); - }); - } -}; diff --git a/database/migrations/2025_02_14_142819_create_historykegiatan_table.php b/database/migrations/2025_02_14_142819_create_historykegiatan_table.php index ac485b3..651ff7a 100644 --- a/database/migrations/2025_02_14_142819_create_historykegiatan_table.php +++ b/database/migrations/2025_02_14_142819_create_historykegiatan_table.php @@ -11,10 +11,11 @@ return new class extends Migration */ public function up(): void { - Schema::create('historykegiatan', function (Blueprint $table) { + Schema::create('HistoryKegiatan', function (Blueprint $table) { $table->id('HistoryKegiatanId'); $table->string('NamaHistoryKegiatan'); - $table->boolean('IsPublish')->default(0); + $table->boolean('IsPublish')->default(1); + $table->softDeletes(); $table->timestamps(); }); } @@ -24,6 +25,6 @@ return new class extends Migration */ public function down(): void { - Schema::dropIfExists('historykegiatan'); + Schema::dropIfExists('HistoryKegiatan'); } }; diff --git a/database/migrations/2025_02_14_153943_create_jeniskegiatan_table.php b/database/migrations/2025_02_14_153943_create_jeniskegiatan_table.php index 0f536d4..dd389a2 100644 --- a/database/migrations/2025_02_14_153943_create_jeniskegiatan_table.php +++ b/database/migrations/2025_02_14_153943_create_jeniskegiatan_table.php @@ -11,10 +11,11 @@ return new class extends Migration */ public function up(): void { - Schema::create('jeniskegiatan', function (Blueprint $table) { + Schema::create('JenisKegiatan', function (Blueprint $table) { $table->id('JenisKegiatanId'); $table->string('NamaJenisKegiatan'); - $table->boolean('IsPublish')->default(0); + $table->boolean('IsPublish')->default(1); + $table->softDeletes(); $table->timestamps(); }); } @@ -24,6 +25,6 @@ return new class extends Migration */ public function down(): void { - Schema::dropIfExists('jeniskegiatan'); + Schema::dropIfExists('JenisKegiatan'); } }; diff --git a/database/migrations/2025_02_17_083731_add_softdeletes_to_jeniskegiatan_table.php b/database/migrations/2025_02_17_083731_add_softdeletes_to_jeniskegiatan_table.php deleted file mode 100644 index 2fced1d..0000000 --- a/database/migrations/2025_02_17_083731_add_softdeletes_to_jeniskegiatan_table.php +++ /dev/null @@ -1,28 +0,0 @@ -softDeletes()->after('IsPublish'); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::table('JenisKegiatan', function (Blueprint $table) { - $table->dropSoftDeletes(); - }); - } -}; diff --git a/database/migrations/2025_02_17_084617_add_softdeletes_to_historykegiatan_table.php b/database/migrations/2025_02_17_084617_add_softdeletes_to_historykegiatan_table.php deleted file mode 100644 index 03bb9b1..0000000 --- a/database/migrations/2025_02_17_084617_add_softdeletes_to_historykegiatan_table.php +++ /dev/null @@ -1,28 +0,0 @@ -softDeletes()->after('IsPublish'); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::table('HistoryKegiatan', function (Blueprint $table) { - $table->dropSoftDeletes(); - }); - } -}; diff --git a/database/migrations/2025_02_17_100043_modify_nama_kategori_to_non_unique.php b/database/migrations/2025_02_17_100043_modify_nama_kategori_to_non_unique.php deleted file mode 100644 index f8d0695..0000000 --- a/database/migrations/2025_02_17_100043_modify_nama_kategori_to_non_unique.php +++ /dev/null @@ -1,28 +0,0 @@ -dropUnique(['NamaKategori']); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::table('Kategori', function (Blueprint $table) { - $table->unique('NamaKategori'); - }); - } -}; diff --git a/database/migrations/2025_02_17_112004_create_perusahaan_table.php b/database/migrations/2025_02_17_112004_create_perusahaan_table.php index 830049b..e6adc26 100644 --- a/database/migrations/2025_02_17_112004_create_perusahaan_table.php +++ b/database/migrations/2025_02_17_112004_create_perusahaan_table.php @@ -30,22 +30,13 @@ return new class extends Migration $table->string('CPTelepon')->nullable(); $table->string('ILNomor')->nullable(); $table->string('ILTanggal')->nullable(); + $table->string('ILDokumen')->nullable(); $table->unsignedBigInteger('JenisDokILId'); $table->foreign('JenisDokILId')->references('JenisDokILId')->on('JenisDokIL')->onDelete('cascade'); $table->unsignedBigInteger('VerifikatorId'); $table->foreign('VerifikatorId')->references('VerifikatorId')->on('Verifikator')->onDelete('cascade'); $table->boolean('ReportLocked')->default(1); - $table->boolean('IsPublish')->default(0); - $table->string('ILDokumen')->nullable(); - $table->string('ILPdlNomor')->default('n')->comment('Dok IL versi PDL'); - $table->unsignedInteger('ILPdlJenis')->nullable()->comment('id dari refjenisdokil'); - $table->foreign('ILPdlJenis')->references('JenisDokILId')->on('JenisDokIL')->onDelete('set null'); - $table->string('DocPdlOrig')->nullable()->comment('nama file original'); - $table->string('DocPdlHash')->nullable()->comment('nama file hash'); - $table->string('DocPdlPath')->nullable()->comment('upload path'); - $table->date('ILPdlTanggal')->nullable(); - $table->unsignedInteger('Kawasan')->nullable()->comment('id dari perusahaan, digunakan utk pengelola kawasan'); - $table->foreign('Kawasan')->references('PerusahaanId')->on('Perusahaan')->onDelete('set null'); + $table->boolean('IsPublish')->default(1); $table->timestamps(); diff --git a/database/migrations/2025_02_17_124317_create_jenisdokumen__i_l_table.php b/database/migrations/2025_02_17_124317_create_jenisdokumen__i_l_table.php index f046e02..6b17d7b 100644 --- a/database/migrations/2025_02_17_124317_create_jenisdokumen__i_l_table.php +++ b/database/migrations/2025_02_17_124317_create_jenisdokumen__i_l_table.php @@ -13,7 +13,6 @@ return new class extends Migration { Schema::create('JenisDokIL', function (Blueprint $table) { $table->id('JenisDokILId'); - $table->string('KodeJenisDokIL')->unique(); $table->string('NamaJenisDokIL'); $table->timestamps(); }); diff --git a/database/migrations/2025_02_17_124903_create_verifikator_table.php b/database/migrations/2025_02_17_124903_create_verifikator_table.php index 3a9016b..a48140c 100644 --- a/database/migrations/2025_02_17_124903_create_verifikator_table.php +++ b/database/migrations/2025_02_17_124903_create_verifikator_table.php @@ -16,6 +16,7 @@ return new class extends Migration $table->string('NamaUnitKerja'); $table->string('NamaKepala'); $table->string('NIP'); + $table->softDeletes(); $table->timestamps(); }); } diff --git a/package-lock.json b/package-lock.json index 9c4fdb0..5fbab63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "DLH-SKL", + "name": "skl2025", "lockfileVersion": 3, "requires": true, "packages": { @@ -8,6 +8,7 @@ "@iconify/react": "^5.2.0", "@radix-ui/react-alert-dialog": "^1.0.5", "@radix-ui/react-avatar": "^1.1.1", + "@radix-ui/react-checkbox": "^1.1.4", "@radix-ui/react-collapsible": "^1.1.1", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-dropdown-menu": "^2.1.2", @@ -1240,6 +1241,77 @@ } } }, + "node_modules/@radix-ui/react-checkbox": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.4.tgz", + "integrity": "sha512-wP0CPAHq+P5I4INKe3hJrIa1WoNqqrejzW+zoU0rOvo1b9gDEJJFl2rYfO1PYJUQCc2H1WZxIJmyv9BS8i5fLw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-primitive": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz", + "integrity": "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.2.tgz", + "integrity": "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-collapsible": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.2.tgz", diff --git a/package.json b/package.json index 4b772e2..0f12c49 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@iconify/react": "^5.2.0", "@radix-ui/react-alert-dialog": "^1.0.5", "@radix-ui/react-avatar": "^1.1.1", + "@radix-ui/react-checkbox": "^1.1.4", "@radix-ui/react-collapsible": "^1.1.1", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-dropdown-menu": "^2.1.2", diff --git a/resources/js/components/Dashboard/ChartCard.tsx b/resources/js/components/Dashboard/ChartCard.tsx index 5aa5a4e..805c5e7 100644 --- a/resources/js/components/Dashboard/ChartCard.tsx +++ b/resources/js/components/Dashboard/ChartCard.tsx @@ -1,13 +1,17 @@ -"use client"; - -import { TrendingUp } from "lucide-react"; -import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"; - +import { useState } from "react"; +import { TrendingUp, BarChart2 } from "lucide-react"; +import { + Bar, + BarChart, + CartesianGrid, + XAxis, + YAxis, + ResponsiveContainer, +} from "recharts"; import { Card, CardContent, CardDescription, - CardFooter, CardHeader, CardTitle, } from "@/components/ui/card"; @@ -17,10 +21,11 @@ import { ChartTooltip, ChartTooltipContent, } from "@/components/ui/chart"; + const chartData = [ - { month: "Genset", desktop: 186 }, - { month: "Boiler", desktop: 305 }, - { month: "Proses", desktop: 237 }, + { month: "Genset", desktop: 186, color: "#22c55e" }, + { month: "Boiler", desktop: 305, color: "#16a34a" }, + { month: "Proses", desktop: 237, color: "#15803d" }, ]; const chartConfig = { @@ -31,40 +36,151 @@ const chartConfig = { } satisfies ChartConfig; export function ChartCard() { + const [activeIndex, setActiveIndex] = useState(null); + + const handleMouseEnter = (index: number) => { + setActiveIndex(index); + }; + + const handleMouseLeave = () => { + setActiveIndex(null); + }; + return ( - - - Sumber Emisi - {/* January - June 2024 */} + +
+ + +
+ + + Sumber Emisi + +
+ + Total Emisi per Sumber +
- - - - - value.slice(0, 3)} - /> - } - /> - - - + + +
+ + + + {chartData.map((entry, index) => ( + + + + + ))} + + + + + + + + + { + if (active && payload && payload.length) { + return ( +
+

+ {payload[0].payload.month} +

+

+ {payload[0].value} ton CO₂ +

+
+ ); + } + return null; + }} + /> + + + handleMouseEnter(index) + } + onMouseLeave={handleMouseLeave} + > + {chartData.map((entry, index) => ( + + ))} + +
+
+
+ +
+ {chartData.map((item, index) => ( +
handleMouseEnter(index)} + onMouseLeave={handleMouseLeave} + > +
+ + {item.month} + +
+ ))} +
- {/* -
- Trending up by 5.2% this month{" "} - -
-
- Showing total visitors for the last 6 months -
-
*/} ); } diff --git a/resources/js/components/Partials/Pengumuman.tsx b/resources/js/components/Partials/Pengumuman.tsx index 09416c0..ed36d91 100644 --- a/resources/js/components/Partials/Pengumuman.tsx +++ b/resources/js/components/Partials/Pengumuman.tsx @@ -97,7 +97,7 @@ const AnnouncementSection = ({ posts }: CardPengumumanProps) => { {/* List of Announcements */} {posts.length > 1 && (
- {posts.slice(1).map((post) => ( + {posts.slice(1, 4).map((post) => ( { - Search + Ketik Pencarianmu di sini...
{ {/* List of Announcements */}
- {undangan.map((item) => ( + {undangan.slice(0, 3).map((item) => ( void; + onSuccess: () => void; + jenisKegiatan: JenisKegiatan[]; + jenisDokIL: JenisDokIL[]; + verifikator: Verifikator[]; + kabupaten: Kabupaten[]; + kecamatan: Kecamatan[]; + kelurahan: Kelurahan[]; + perusahaan: Perusahaan[]; + // kawasan: Kawasan[]; + // existingPerusahaan: ExistingPerusahaan[]; + // existingInduk: ExistingInduk[]; +} + +export function AddPerusahaanModal({ + open, + onClose, + onSuccess, + jenisKegiatan, + jenisDokIL, + verifikator, + kabupaten, + kecamatan, + kelurahan, + perusahaan, +}: // existingPerusahaan, +// existingInduk, +// kawasan, +AddPerusahaanModalProps) { + const { toast } = useToast(); + const [loading, setLoading] = useState(false); + const [date, setDate] = useState(); + const { data, setData, post, reset } = useForm({ + NomorInduk: "", + PerusahaanId: "", + JenisKegiatanId: "", + NamaPerusahaan: "", + Alamat: "", + KelurahanId: "", + KodePos: "", + Telepon: "", + Fax: "", + Email: "", + Lintang: "", + Bujur: "", + CPNama: "", + CPTelepon: "", + JenisDokILId: "", + VerifikatorId: "", + IsPublish: true, + ILDokumen: null as File | null, + ILNomor: "", + ILTanggal: "", + ReportLocked: true, + }); + + const [selectedKabupaten, setSelectedKabupaten] = useState<{ + value: number; + label: string; + } | null>(null); + + const [selectedKecamatan, setSelectedKecamatan] = useState<{ + value: number; + label: string; + } | null>(null); + + const [selectedKelurahan, setSelectedKelurahan] = useState<{ + value: number; + label: string; + } | null>(null); + + const [selectedPerusahaan, setSelectedPerusahaan] = useState<{ + value: number; + label: string; + } | null>(null); + + const jenisKegiatanOptions = jenisKegiatan.map((jk) => ({ + value: jk.JenisKegiatanId, + label: jk.NamaJenisKegiatan, + })); + + const jenisDokILOptions = jenisDokIL.map((jdi) => ({ + value: jdi.JenisDokILId, + label: jdi.NamaJenisDokIL, + })); + + const verifikatorOptions = verifikator.map((v) => ({ + value: v.VerifikatorId, + label: v.NamaUnitKerja, + })); + + const kabupatenOptions = kabupaten.map((k) => ({ + value: k.KabupatenId, + label: k.NamaKabupaten, + })); + + const perusahaanOptions = perusahaan.map((per) => ({ + value: per.PerusahaanId, + label: per.PerusahaanId, + })); + + const kecamatanOptions = kecamatan + .filter( + (kec) => + selectedKabupaten && kec.KabupatenId === selectedKabupaten.value + ) + .map((kec) => ({ + value: kec.KecamatanId, + label: kec.NamaKecamatan, + })); + + const kelurahanOptions = kelurahan + .filter( + (kel) => + selectedKecamatan && kel.KecamatanId === selectedKecamatan.value + ) + .map((kel) => ({ + value: kel.KelurahanId, + label: kel.NamaKelurahan, + })); + + const [showAlert, setShowAlert] = useState(false); + const [errors, setErrors] = useState>({}); + + const validateForm = () => { + const newErrors: Record = {}; + + // const titleExists = existingPerusahaan.some( + // (perus) => + // perus.PerusahaanId.toLowerCase() === + // data.PerusahaanId.toLowerCase() + // ); + + // const indukExists = existingInduk.some( + // (induk) => + // induk.NomorInduk.toLowerCase() === data.NomorInduk.toLowerCase() + // ); + + // if (indukExists) { + // setShowAlert(true); + // newErrors.NomorInduk = "Nomor Induk sudah ada"; + // // Auto-hide alert after 5 seconds + // setTimeout(() => setShowAlert(false), 5000); + // } + + // if (titleExists) { + // setShowAlert(true); + // newErrors.NamaPerusahaan = "Nama Perusahaan sudah ada"; + // // Auto-hide alert after 5 seconds + // setTimeout(() => setShowAlert(false), 5000); + // } + + // if (!data.PerusahaanId) { + // newErrors.PerusahaanId = "Perusahaan harus diisi"; + // } + if (!data.JenisKegiatanId) { + newErrors.JenisKegiatanId = "Jenis Kegiatan harus dipilih"; + } + if (!data.VerifikatorId) { + newErrors.VerifikatorId = "Admin harus dipilih"; + } + if (!data.Email) { + newErrors.Email = "Email harus diisi"; + } + + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + + if (!validateForm()) { + toast({ + title: "Validasi Gagal", + description: "Silakan periksa kembali form anda", + variant: "destructive", + }); + return; + } + + setLoading(true); + + const formData = new FormData(); + + formData.append("NomorInduk", data.NomorInduk); + formData.append("JenisKegiatanId", data.JenisKegiatanId); + formData.append("VerifikatorId", data.VerifikatorId); + formData.append("KelurahanId", data.KelurahanId); + formData.append("NamaPerusahaan", data.NamaPerusahaan); + formData.append("Alamat", data.Alamat); + formData.append("KodePos", data.KodePos); + formData.append("Telepon", data.Telepon); + formData.append("Fax", data.Fax); + formData.append("Email", data.Email); + formData.append("Lintang", data.Lintang); + formData.append("Bujur", data.Bujur); + formData.append("CPNama", data.CPNama); + formData.append("CPTelepon", data.CPTelepon); + formData.append("JenisDokILId", data.JenisDokILId); + formData.append("IsPublish", data.IsPublish.toString()); + formData.append("ILNomor", data.ILNomor); + formData.append("ILTanggal", data.ILTanggal); + formData.append("ReportLocked", data.ReportLocked.toString()); + + if (data.ILDokumen) { + formData.append("ILDokumen", data.ILDokumen); + } + + post("/admin/perusahaan", { + data: formData, + forceFormData: true, + onSuccess: (response) => { + toast({ + title: "Berhasil", + description: "Perusahaan berhasil ditambahkan", + variant: "default", + }); + reset(); + onSuccess(); + onClose(); + }, + onError: (error) => { + console.error("Error:", error); + toast({ + title: "Gagal", + description: + "Terjadi kesalahan saat menambahkan perusahaan", + variant: "destructive", + }); + }, + }); + }; + + return ( + + + + Tambah Perusahaan Baru + + Masukkan informasi perusahaan yang akan ditambahkan ke + dalam sistem. + + + +
+ {/* Sisi Kiri */} +
+
+
+ +

+ Data Perusahaan +

+
+ +
+ + + setData({ + ...data, + NomorInduk: e.target.value, + }) + } + /> + {errors.NomorInduk && ( +

+ {errors.NomorInduk} +

+ )} +
+ +
+ + + setData({ + ...data, + NamaPerusahaan: e.target.value, + }) + } + /> + {errors.PerusahaanId && ( +

+ {errors.PerusahaanId} +

+ )} +
+
+ + + setData({ + ...data, + VerifikatorId: + option?.value?.toString() || + "", + }) + } + /> + {errors.VerifikatorId && ( +

+ {errors.VerifikatorId} +

+ )} +
+ +
+ + + setData({ + ...data, + CPNama: e.target.value, + }) + } + /> +
+ +
+ + + setData({ + ...data, + CPTelepon: e.target.value, + }) + } + /> +
+
+ + + {/* Dokumen Izin */} +
+
+ +

+ Dokumen Izin +

+
+ +
+ + + setData({ + ...data, + ILNomor: e.target.value, + }) + } + /> +
+ +
+ + + setData({ + ...data, + ILTanggal: e.target.value, + }) + } + /> +
+ +
+ + + setData({ + ...data, + ILDokumen: e.target.files + ? e.target.files[0] + : null, + }) + } + /> +
+
+
+
+ + {/* Sisi Kanan */} +
+
+
+ +

+ Alamat Perusahaan +

+
+
+ + { + setSelectedKecamatan(value); + setSelectedKelurahan(null); + }} + placeholder="Pilih Kecamatan" + isSearchable + isDisabled={!selectedKabupaten} + required + /> +
+ +
+ +