diff --git a/resources/js/components/PerizinanLingkungan/FilterPencarian.tsx b/resources/js/components/PerizinanLingkungan/FilterPencarian.tsx new file mode 100644 index 0000000..794124c --- /dev/null +++ b/resources/js/components/PerizinanLingkungan/FilterPencarian.tsx @@ -0,0 +1,336 @@ +import React, { useState } from "react"; +import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import Select from "react-select"; +import { CalendarIcon, Search } from "lucide-react"; +import { format } from "date-fns"; +import { DateRange } from "react-day-picker"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { Calendar as UIDatePicker } from "@/components/ui/calendar"; +import { + Perusahaan, + JenisDokIL, + JenisKegiatan, + PerizinanLingkunganType, +} from "@/types/perusahaan"; + +type SelectOption = { + value: string; + label: string; +}; + +type FilterPerizinanLingkunganProps = { + perusahaan?: Perusahaan[]; + jenisDokIL?: JenisDokIL[]; + jenisKegiatan?: JenisKegiatan[]; + izinLingkungan?: PerizinanLingkunganType[]; + onSearch: (filters: { + selectedPerusahaan: SelectOption | null; + selectedJenisKegiatan: SelectOption | null; + Alamat: string; + TeleponFax: string; + Email: string; + selectedJenisIzin: SelectOption | null; + ILNomor: string; + ILTanggal: string | null; + }) => void; +}; + +export default function FilterPerizinanLingkungan({ + perusahaan = [], + jenisDokIL = [], + jenisKegiatan = [], + onSearch, +}: FilterPerizinanLingkunganProps) { + const [dateRange, setDateRange] = useState({ + from: undefined, + to: undefined, + }); + + const perusahaanOptions: SelectOption[] = perusahaan.map((p) => ({ + value: p.PerusahaanId.toString(), + label: p.NamaPerusahaan, + })); + + const jenisKegiatanOptions: SelectOption[] = jenisKegiatan.map((jk) => ({ + value: jk.JenisKegiatanId.toString(), + label: jk.NamaJenisKegiatan, + })); + + const jenisIzinOptions: SelectOption[] = jenisDokIL.map((jdi) => ({ + value: jdi.JenisDokILId.toString(), + label: jdi.NamaJenisDokIL, + })); + + const selectStyles = { + control: (base: any) => ({ + ...base, + minHeight: "38px", + borderRadius: "0.375rem", + borderColor: "#e2e8f0", + boxShadow: "none", + "&:hover": { + borderColor: "#cbd5e0", + }, + }), + }; + + const [selectedPerusahaan, setSelectedPerusahaan] = + useState(null); + const [selectedJenisKegiatan, setSelectedJenisKegiatan] = + useState(null); + const [Alamat, setAlamat] = useState(""); + const [TeleponFax, setTeleponFax] = useState(""); + const [Email, setEmail] = useState(""); + const [selectedJenisIzin, setSelectedJenisIzin] = + useState(null); + const [ILNomor, setILNomor] = useState(""); + const [ILTanggal, setILTanggal] = useState(null); + + function handleSearch() { + let formattedDate: string | null = null; + if (dateRange?.from && dateRange?.to) { + // Jika kedua tanggal dipilih, format sebagai rentang + formattedDate = `${format(dateRange.from, "yyyy-MM-dd")} - ${format( + dateRange.to, + "yyyy-MM-dd" + )}`; + } else if (dateRange?.from) { + // Jika hanya tanggal mulai yang dipilih, gunakan tanggal tersebut + formattedDate = format(dateRange.from, "yyyy-MM-dd"); + } + onSearch({ + selectedPerusahaan, + selectedJenisKegiatan, + Alamat, + TeleponFax, + Email, + selectedJenisIzin, + ILNomor, + ILTanggal: formattedDate, + }); + } + function handleReset() { + // Reset all form state + setDateRange({ from: undefined, to: undefined }); + setSelectedPerusahaan(null); + setSelectedJenisKegiatan(null); + setAlamat(""); + setTeleponFax(""); + setEmail(""); + setSelectedJenisIzin(null); + setILNomor(""); + setILTanggal(null); + + // Reset the search results by calling onSearch with empty/default values + onSearch({ + selectedPerusahaan: null, + selectedJenisKegiatan: null, + Alamat: "", + TeleponFax: "", + Email: "", + selectedJenisIzin: null, + ILNomor: "", + ILTanggal: null, + }); + } + + return ( +
+ + + + Filter Pencarian Perizinan Lingkungan + + + +
+ {/* Kolom Kiri */} +
+
+ +
+ + "Tidak ada data" + } + /> +
+
+
+ +
+ + setAlamat(e.target.value) + } + /> +
+
+
+ +
+ + setTeleponFax(e.target.value) + } + /> +
+
+
+ {/* Kolom Kanan */} +
+
+ +
+ + setEmail(e.target.value) + } + /> +
+
+
+ +
+ + setILNomor(e.target.value) + } + /> +
+
+
+ +
+ + + + + + + + +
+
+
+
+
+ + +
+
+
+
+ ); +} diff --git a/resources/js/components/PerizinanLingkungan/ModalIzinLingkungan.tsx b/resources/js/components/PerizinanLingkungan/ModalIzinLingkungan.tsx new file mode 100644 index 0000000..610ab32 --- /dev/null +++ b/resources/js/components/PerizinanLingkungan/ModalIzinLingkungan.tsx @@ -0,0 +1,224 @@ +import React, { useState } from "react"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import Select from "react-select"; +import { router } from "@inertiajs/react"; +import { Perusahaan, JenisKegiatan } from "@/types/perusahaan"; + +type ModalIzinLingkunganProps = { + open: boolean; + onClose: () => void; + onSuccess: () => void; + selectedPerusahaan: Perusahaan | null; + jenisKegiatan: JenisKegiatan[]; // Ganti dari jenisDokIL menjadi jenisKegiatan +}; + +export function ModalIzinLingkungan({ + open, + onClose, + onSuccess, + selectedPerusahaan, + jenisKegiatan, +}: ModalIzinLingkunganProps) { + if (!selectedPerusahaan) return null; + + // State untuk field Nomor & Tanggal Izin Lingkungan (contoh) + const [nomorIzin, setNomorIzin] = useState( + selectedPerusahaan.ILNomor || "" + ); + const [tanggalIzin, setTanggalIzin] = useState( + selectedPerusahaan.ILTanggal + ? new Date(selectedPerusahaan.ILTanggal).toISOString().split("T")[0] + : "" + ); + const [dokumen, setDokumen] = useState(null); + + // State untuk dropdown Jenis Kegiatan + // Jika perusahaan sudah memiliki jenis_kegiatan, kita set default-nya + const [selectedJenisKegiatan, setSelectedJenisKegiatan] = useState<{ + value: number; + label: string; + } | null>( + selectedPerusahaan.jenis_kegiatan + ? { + value: selectedPerusahaan.jenis_kegiatan.JenisKegiatanId, + label: selectedPerusahaan.jenis_kegiatan.NamaJenisKegiatan, + } + : null + ); + + // Konversi data jenisKegiatan agar bisa dibaca oleh react-select + const jenisKegiatanOptions = jenisKegiatan.map((jk) => ({ + value: jk.JenisKegiatanId, + label: jk.NamaJenisKegiatan, + })); + + // Handler submit form + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (!selectedPerusahaan) return; + + // Siapkan FormData untuk dikirim via Inertia + const formData = new FormData(); + formData.append( + "PerusahaanId", + String(selectedPerusahaan.PerusahaanId) + ); + formData.append("ILNomor", nomorIzin); + formData.append("ILTanggal", tanggalIzin); + // Ganti JenisDokILId -> JenisKegiatanId (sesuaikan dengan field di DB) + formData.append( + "JenisKegiatanId", + selectedJenisKegiatan?.value.toString() || "" + ); + if (dokumen) { + formData.append("ILDokumen", dokumen); + } + + router.post( + `/admin/perizinan_lingkungan/${selectedPerusahaan.PerusahaanId}`, + formData, + { + onSuccess: () => { + onSuccess(); // menutup modal & refresh data + }, + } + ); + }; + + return ( + + + + Perizinan Lingkungan + + + {/* Detail perusahaan */} +
+
+
No Induk:
+
{selectedPerusahaan.NomorInduk || "-"}
+ +
Perusahaan:
+
{selectedPerusahaan.NamaPerusahaan || "-"}
+ +
Jenis Kegiatan:
+
+ {selectedPerusahaan.jenis_kegiatan + ?.NamaJenisKegiatan || "-"} +
+ +
Alamat:
+
{selectedPerusahaan.Alamat || "-"}
+ +
Telepon:
+
{selectedPerusahaan.Telepon || "-"}
+ +
Fax:
+
{selectedPerusahaan.Fax || "-"}
+ +
Email:
+
{selectedPerusahaan.Email || "-"}
+
+
+ + {/* Form update dokumen izin */} +
+
+ + setNomorIzin(e.target.value)} + /> +
+ +
+ + setTanggalIzin(e.target.value)} + /> +
+ +
+ + { + if ( + e.target.files && + e.target.files.length > 0 + ) { + setDokumen(e.target.files[0]); + } + }} + /> +
+ + {selectedPerusahaan.ILDokumen && ( +
+ +
+ )} + +
+ + +
+
+
+
+ ); +} diff --git a/resources/js/components/pagination.jsx b/resources/js/components/pagination.jsx new file mode 100644 index 0000000..672f360 --- /dev/null +++ b/resources/js/components/pagination.jsx @@ -0,0 +1,32 @@ +import React from "react"; +import { Link } from "@inertiajs/react"; + +const Pagination = ({ links }) => { + return ( + + ); +}; + +export default Pagination; diff --git a/resources/js/pages/admin/pelaporan/index_pelaporan.tsx b/resources/js/pages/admin/pelaporan/index_pelaporan.tsx index daa4c41..04bca91 100644 --- a/resources/js/pages/admin/pelaporan/index_pelaporan.tsx +++ b/resources/js/pages/admin/pelaporan/index_pelaporan.tsx @@ -25,6 +25,7 @@ import { } from "lucide-react"; import Select from "react-select"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; interface SKLData { no: number; @@ -87,59 +88,76 @@ export default function PelaporanIndex() {
{/* Filter Section */} -
-
-
- - setYear(e.target.value)} - className="w-24" - /> +
+ + setYear(e.target.value) + } + className="w-full sm:w-24" + /> - + setQuarter( + newValue?.value || + "Triwulan 1" + ) + } + placeholder="Pilih Periode" + className="w-full sm:w-[150px]" + /> +
- -
+ +
- {/*
+ {/*
*/} -
+
+ +
{/* Table Section */} @@ -284,14 +304,14 @@ export default function PelaporanIndex() { 00.00 00.00 @@ -300,37 +320,37 @@ export default function PelaporanIndex() { 00.00 76.70 76.70 76.70 76.70 76.70 @@ -362,69 +382,69 @@ export default function PelaporanIndex() { */} {/* Legend Section */} -
+
{/* Keterangan Section */} -
+

Keterangan

-
+
-
+

SKL : Status Ketaatan Lingkungan

-
+

SPBM : Status Pemenuhan Baku Mutu

-
+

IL : Ijin Lingkungan

-
+

AL : Air Limbah

-
+

LB3 : Limbah B3

-
+

SB : Sumber Bergerak

-
+

BS : Kebisingan & Udara Ambien

-
+

STB : Sumber Tidak Bergerak

-
+

LP : Limbah Padat

-
+

KDM : Kawasan Dilarang Merokok

@@ -432,15 +452,15 @@ export default function PelaporanIndex() {
-
+

STT : Surat Tanda Terima

-
+
-
+

SE : Surat Evaluasi

@@ -450,34 +470,34 @@ export default function PelaporanIndex() {
{/* Status Data Section */} -
+

Status Data

-
+
-
+

Data belum diisi

-
+

Data telah diisi dan belum diverifikasi

-
+

Data telah siap untuk diverifikasi

-
+

Data telah diisi dan diverifikasi

diff --git a/routes/web.php b/routes/web.php index 1bb84aa..a675906 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,5 +1,7 @@ name('home'); @@ -70,9 +75,23 @@ Route::get('/search', [SearchController::class, 'index'])->name('search'); // Dashboard Route -Route::get('/dashboard', function () { - return Inertia::render('dashboard'); -})->middleware(['auth'])->name('dashboard'); +// Route::get('/dashboard', function () { +// return Inertia::render('dashboard'); +// })->middleware(['auth','permission:Dashboard.index' ])->name('dashboard'); +Route::middleware(['auth', PermissionMiddleware::using('Dashboard.index')])->group(function () { + Route::get('/dashboard', DashboardController::class)->name('dashboard'); +}); + +// buatkan route untuk view dashboard_other, tanpa auth dan middleware, jadi langsung nembak url +Route::get('/dashboard_other', function () { + return Inertia::render('dashboard_other'); +})->name('dashboard_other'); + +Route::get('/dashboard_perusahaan', function () { + return Inertia::render('dashboard_perusahaan'); +})->name('dashboard_perusahaan'); + + Route::middleware(['auth'])->group(function () { Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit'); @@ -165,10 +184,11 @@ Route::middleware(['auth'])->prefix('admin')->group(function () { Route::middleware(['auth'])->prefix('admin')->group(function () { Route::get('/history_perusahaan', [HistoryPerusahaanController::class, 'index'])->name('admin.history_perusahaan.index'); Route::get('/history_perusahaan/add', [HistoryPerusahaanController::class, 'create'])->name('admin.history_perusahaan.create'); - Route::post('/history_perusahaan', [HistoryPerusahaanController::class, 'store'])->name('admin.history_perusahaan.store'); Route::get('/history_perusahaan/{history_perusahaan}', [HistoryPerusahaanController::class, 'edit'])->name('admin.history_perusahaan.edit'); Route::post('/history_perusahaan/{history_perusahaan}', [HistoryPerusahaanController::class, 'update'])->name('admin.history_perusahaan.update'); Route::delete('/history_perusahaan/{history_perusahaan}', [HistoryPerusahaanController::class, 'destroy'])->name('admin.history_perusahaan.destroy'); + Route::get('/history_perusahaan/detail/{perusahaanId}', [HistoryPerusahaanController::class, 'detail'])->name('admin.history_perusahaan.detail'); + Route::post('/history_perusahaan/detail/{perusahaanId}/store', [HistoryPerusahaanController::class, 'store'])->name('admin.history_perusahaan.store'); }); Route::middleware(['auth'])->prefix('admin')->group(function () { @@ -189,4 +209,39 @@ Route::middleware(['auth'])->prefix('admin')->group(function () { Route::delete('/perusahaan/{perusahaan}', [PerusahaanController::class, 'destroy'])->name('admin.perusahaan.destroy'); }); +Route::middleware(['auth'])->prefix('admin')->group(function () { + Route::get('/perizinan_lingkungan', [PerizinanLingkunganController::class, 'index'])->name('admin.perizinan_lingkungan.index'); + Route::post('/perizinan_lingkungan/{perusahaan}', [PerizinanLingkunganController::class, 'update'])->name('admin.perizinan_lingkungan.update'); +}); + +// Route::middleware(['auth'])->prefix('admin')->name('admin.')->group(function () { +// Route::get('/roles', [RolesController::class, 'index'])->name('roles.index'); +// Route::get('/roles/add', [RolesController::class, 'create'])->name('roles.create'); +// Route::post('/roles', [RolesController::class, 'store'])->name('roles.store'); +// Route::get('/roles/{role}', [RolesController::class, 'edit'])->name('roles.edit'); +// Route::post('/roles/{role}', [RolesController::class, 'update'])->name('roles.update'); +// Route::delete('/roles/{role}', [RolesController::class, 'destroy'])->name('roles.destroy'); +// }); + +// Route::prefix('admin')->middleware(['auth'])->name('admin.')->group(function () { +// Route::get('/roles', \App\Http\Controllers\Admin\RoleController::class)->name('roles')->middleware('permission:Roles.index'); + +// $resources = [ +// 'roles' => [ +// 'controller' => \App\Http\Controllers\Admin\RoleController::class, +// 'permissions' => 'Roles.index', +// 'names' => 'Roles' +// ], +// ]; + +// foreach ($resources as $name => $resource) { +// $route = Route::resource($name, $resource['controller']) +// ->middleware("permission:{$resource['permissions']}"); +// if (isset($resource['names'])) { +// $route->names($resource['names']); +// } +// } + +// }); + require __DIR__.'/auth.php';