feat: Menambahkan controller, request, dan halaman index perizinan lingkungan
parent
113d2eb8d1
commit
2d6918cdbc
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\PerizinanLingkunganRequest;
|
||||
use App\Http\Requests\PerusahaanRequest;
|
||||
use App\Models\JenisDokIL;
|
||||
use App\Models\JenisKegiatan;
|
||||
use App\Models\Perusahaan;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class PerizinanLingkunganController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
// Mengambil data perusahaan beserta relasinya (misal: jenis kegiatan & jenis dokumen izin)
|
||||
$perusahaan = Perusahaan::with(['jenisKegiatan', 'jenisDokIL'])->get();
|
||||
// Mengambil data jenis dokumen izin lingkungan
|
||||
$jenisKegiatan = JenisKegiatan::all();
|
||||
$jenisDokIL = JenisDokIL::all();
|
||||
|
||||
return Inertia::render('admin/perizinan_lingkungan/index_perizinan_lingkungan', [
|
||||
'perusahaan' => $perusahaan,
|
||||
'jenisKegiatan' => $jenisKegiatan,
|
||||
'jenisDokIL' => $jenisDokIL,
|
||||
]);
|
||||
}
|
||||
// public function update(PerusahaanRequest $request, Perusahaan $perusahaan)
|
||||
// {
|
||||
// try {
|
||||
// DB::beginTransaction();
|
||||
|
||||
// $data = $request->validated();
|
||||
|
||||
// // Jika tidak ada file ILDokumen yang di-upload, hapus key tersebut agar tidak mengubah nilai sebelumnya
|
||||
// if (!$request->hasFile('ILDokumen')) {
|
||||
// unset($data['ILDokumen']);
|
||||
// } else {
|
||||
// // Jika sudah ada file sebelumnya, hapus file lama terlebih dahulu
|
||||
// if ($perusahaan->ILDokumen && Storage::disk('public')->exists($perusahaan->ILDokumen)) {
|
||||
// Storage::disk('public')->delete($perusahaan->ILDokumen);
|
||||
// }
|
||||
|
||||
// // Buat nama file baru berdasarkan waktu upload dan nama file asli
|
||||
// $fileName = time() . '_' . $request->file('ILDokumen')->getClientOriginalName();
|
||||
// $path = $request->file('ILDokumen')->storeAs('files/il', $fileName, 'public');
|
||||
// $data['ILDokumen'] = $path;
|
||||
// }
|
||||
|
||||
// // Update data perusahaan (termasuk data perizinan lingkungan)
|
||||
// $perusahaan->update($data);
|
||||
|
||||
// DB::commit();
|
||||
|
||||
// return redirect()->route('admin.perizinan_lingkungan.index')
|
||||
// ->with('success', 'Data perizinan lingkungan berhasil diperbarui');
|
||||
// } catch (\Exception $e) {
|
||||
// DB::rollBack();
|
||||
// Log::error('Error updating perizinan lingkungan: ' . $e->getMessage());
|
||||
// return response()->json(['message' => 'Error: ' . $e->getMessage()], 500);
|
||||
// }
|
||||
// }
|
||||
|
||||
// public function update(PerizinanLingkunganRequest $request, Perusahaan $perusahaan)
|
||||
// {
|
||||
// try {
|
||||
// DB::beginTransaction();
|
||||
|
||||
// $data = $request->validated();
|
||||
|
||||
// $perusahaan->ILNomor = $data['ILNomor'] ?? $perusahaan->ILNomor;
|
||||
// $perusahaan->ILTanggal = $data['ILTanggal'] ?? $perusahaan->ILTanggal;
|
||||
// $perusahaan->JenisKegiatanId = $data['JenisKegiatanId'] ?? $perusahaan->JenisKegiatanId;
|
||||
|
||||
// if ($request->hasFile('ILDokumen')) {
|
||||
// if ($perusahaan->ILDokumen && Storage::disk('public')->exists($perusahaan->ILDokumen)) {
|
||||
// Storage::disk('public')->delete($perusahaan->ILDokumen);
|
||||
// }
|
||||
// $file = $request->file('ILDokumen');
|
||||
// $filename = time() . '_' . $file->getClientOriginalName();
|
||||
// $path = $file->storeAs('files/il', $filename, 'public');
|
||||
// $perusahaan->ILDokumen = $path;
|
||||
// }
|
||||
|
||||
// $perusahaan->save();
|
||||
// DB::commit();
|
||||
|
||||
// return redirect()->route('admin.perizinan_lingkungan.index')
|
||||
// ->with('success', 'Data perizinan lingkungan berhasil diperbarui');
|
||||
// } catch (\Exception $e) {
|
||||
// DB::rollBack();
|
||||
// Log::error('Error updating perizinan lingkungan: ' . $e->getMessage());
|
||||
// return back()->withErrors(['error' => $e->getMessage()]);
|
||||
// }
|
||||
// }
|
||||
|
||||
public function update(PerizinanLingkunganRequest $request, Perusahaan $perusahaan)
|
||||
{
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
// Ambil data lengkap dari model (pastikan semua field termasuk yang wajib ada)
|
||||
$existingData = $perusahaan->getAttributes();
|
||||
|
||||
// Ambil data baru hanya dari field perizinan
|
||||
$newData = $request->only(['ILNomor', 'ILTanggal', 'JenisKegiatanId']);
|
||||
|
||||
if ($request->hasFile('ILDokumen')) {
|
||||
if ($perusahaan->ILDokumen && Storage::disk('public')->exists($perusahaan->ILDokumen)) {
|
||||
Storage::disk('public')->delete($perusahaan->ILDokumen);
|
||||
}
|
||||
$file = $request->file('ILDokumen');
|
||||
$filename = time() . '_' . $file->getClientOriginalName();
|
||||
$path = $file->storeAs('files/il', $filename, 'public');
|
||||
$newData['ILDokumen'] = $path;
|
||||
}
|
||||
|
||||
// Gabungkan data lama dengan data baru (field baru akan override data lama)
|
||||
$data = array_merge($existingData, $newData);
|
||||
|
||||
$perusahaan->update($data);
|
||||
|
||||
DB::commit();
|
||||
|
||||
return redirect()->route('admin.perizinan_lingkungan.index')
|
||||
->with('success', 'Data perizinan lingkungan berhasil diperbarui');
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
Log::error('Error updating perizinan lingkungan: ' . $e->getMessage());
|
||||
return back()->withErrors(['error' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class PerizinanLingkunganRequest 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 [
|
||||
'ILNomor' => 'nullable|string',
|
||||
'ILTanggal' => 'nullable|date',
|
||||
'JenisKegiatanId' => 'nullable|exists:JenisKegiatan,JenisKegiatanId',
|
||||
'ILDokumen' => 'nullable|file|mimes:pdf|max:20480',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,285 @@
|
|||
import React, { useState } from "react";
|
||||
import AuthenticatedLayout from "@/layouts/authenticated-layout";
|
||||
import { Head } from "@inertiajs/react";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import FilterPerizinanLingkungan from "@/components/PerizinanLingkungan/FilterPencarian";
|
||||
import { Perusahaan, JenisDokIL, JenisKegiatan } from "@/types/perusahaan";
|
||||
import { FileText } from "lucide-react";
|
||||
import { ModalIzinLingkungan } from "@/components/PerizinanLingkungan/ModalIzinLingkungan";
|
||||
|
||||
type PerizinanLingkunganIndexProps = {
|
||||
perusahaan: Perusahaan[];
|
||||
jenisDokIL: JenisDokIL[];
|
||||
jenisKegiatan: JenisKegiatan[];
|
||||
};
|
||||
|
||||
export default function PerizinanLingkunganIndex({
|
||||
perusahaan,
|
||||
jenisDokIL,
|
||||
jenisKegiatan,
|
||||
}: PerizinanLingkunganIndexProps) {
|
||||
const [selectedPerusahaan, setSelectedPerusahaan] =
|
||||
useState<Perusahaan | null>(null);
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
|
||||
// Handler ketika klik kolom "Jenis Izin"
|
||||
const handleJenisIzinClick = (p: Perusahaan) => {
|
||||
setSelectedPerusahaan(p);
|
||||
setShowModal(true);
|
||||
};
|
||||
|
||||
const handleModalClose = () => {
|
||||
setShowModal(false);
|
||||
setSelectedPerusahaan(null);
|
||||
};
|
||||
|
||||
// Callback jika upload dokumen sukses, maka reload atau refresh data
|
||||
const handleUploadSuccess = () => {
|
||||
setShowModal(false);
|
||||
setSelectedPerusahaan(null);
|
||||
// contoh reload:
|
||||
// window.location.reload();
|
||||
// atau bisa panggil inertia visit:
|
||||
// router.reload();
|
||||
};
|
||||
|
||||
// State untuk data yang ditampilkan pada tabel
|
||||
const [filteredPerusahaan, setFilteredPerusahaan] =
|
||||
useState<Perusahaan[]>(perusahaan);
|
||||
|
||||
// Callback dari FilterPerizinanLingkungan
|
||||
const handleSearch = (filters: {
|
||||
selectedPerusahaan: { value: string; label: string } | null;
|
||||
selectedJenisKegiatan: { value: string; label: string } | null;
|
||||
Alamat: string;
|
||||
TeleponFax: string;
|
||||
Email: string;
|
||||
selectedJenisIzin: { value: string; label: string } | null;
|
||||
ILNomor: string;
|
||||
ILTanggal: string | null;
|
||||
}) => {
|
||||
let result = [...perusahaan];
|
||||
|
||||
if (filters.selectedPerusahaan) {
|
||||
result = result.filter(
|
||||
(p) =>
|
||||
p.PerusahaanId.toString() ===
|
||||
filters.selectedPerusahaan?.value
|
||||
);
|
||||
}
|
||||
if (filters.selectedJenisKegiatan) {
|
||||
result = result.filter(
|
||||
(p) =>
|
||||
p.JenisKegiatanId?.toString() ===
|
||||
filters.selectedJenisKegiatan?.value
|
||||
);
|
||||
}
|
||||
if (filters.Alamat.trim() !== "") {
|
||||
result = result.filter((p) =>
|
||||
p.Alamat?.toLowerCase().includes(filters.Alamat.toLowerCase())
|
||||
);
|
||||
}
|
||||
if (filters.TeleponFax.trim() !== "") {
|
||||
result = result.filter((p) => {
|
||||
const telMatch = p.Telepon?.toLowerCase().includes(
|
||||
filters.TeleponFax.toLowerCase()
|
||||
);
|
||||
const faxMatch = p.Fax?.toLowerCase().includes(
|
||||
filters.TeleponFax.toLowerCase()
|
||||
);
|
||||
return telMatch || faxMatch;
|
||||
});
|
||||
}
|
||||
if (filters.Email.trim() !== "") {
|
||||
result = result.filter((p) =>
|
||||
p.Email?.toLowerCase().includes(filters.Email.toLowerCase())
|
||||
);
|
||||
}
|
||||
if (filters.selectedJenisIzin) {
|
||||
result = result.filter(
|
||||
(p) =>
|
||||
p.JenisDokILId?.toString() ===
|
||||
filters.selectedJenisIzin?.value
|
||||
);
|
||||
}
|
||||
if (filters.ILNomor.trim() !== "") {
|
||||
result = result.filter((p) =>
|
||||
p.ILNomor?.toLowerCase().includes(filters.ILNomor.toLowerCase())
|
||||
);
|
||||
}
|
||||
if (filters.ILTanggal) {
|
||||
// Asumsikan format filter "yyyy-MM-dd" atau "yyyy-MM-dd - yyyy-MM-dd"
|
||||
if (filters.ILTanggal.includes(" - ")) {
|
||||
const [from, to] = filters.ILTanggal.split(" - ");
|
||||
result = result.filter((p) => {
|
||||
if (!p.ILTanggal) return false;
|
||||
const itemDate = format(
|
||||
new Date(p.ILTanggal),
|
||||
"yyyy-MM-dd"
|
||||
);
|
||||
return itemDate >= from && itemDate <= to;
|
||||
});
|
||||
} else {
|
||||
result = result.filter((p) => {
|
||||
if (!p.ILTanggal) return false;
|
||||
const itemDate = format(
|
||||
new Date(p.ILTanggal),
|
||||
"yyyy-MM-dd"
|
||||
);
|
||||
return itemDate === filters.ILTanggal;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setFilteredPerusahaan(result);
|
||||
};
|
||||
|
||||
return (
|
||||
<AuthenticatedLayout header="Perizinan Lingkungan">
|
||||
<Head title="Perizinan Lingkungan" />
|
||||
|
||||
<ModalIzinLingkungan
|
||||
open={showModal}
|
||||
onClose={handleModalClose}
|
||||
onSuccess={handleUploadSuccess}
|
||||
selectedPerusahaan={selectedPerusahaan}
|
||||
// jenisDokIL={jenisDokIL}
|
||||
jenisKegiatan={jenisKegiatan}
|
||||
/>
|
||||
|
||||
{/* Komponen Filter */}
|
||||
<FilterPerizinanLingkungan
|
||||
perusahaan={perusahaan}
|
||||
jenisDokIL={jenisDokIL}
|
||||
jenisKegiatan={jenisKegiatan}
|
||||
izinLingkungan={[]} // bisa dihilangkan jika filtering dilakukan pada data perusahaan
|
||||
onSearch={handleSearch}
|
||||
/>
|
||||
|
||||
{/* Tabel Data */}
|
||||
<div className="w-full overflow-x-auto">
|
||||
<Table className="min-w-[900px] border-collapse">
|
||||
<TableHeader>
|
||||
<TableRow className="border-b bg-green-800">
|
||||
<TableHead className="text-white text-center border-r w-16">
|
||||
No.
|
||||
</TableHead>
|
||||
<TableHead className="text-white text-center border-r">
|
||||
Nama Perusahaan
|
||||
</TableHead>
|
||||
<TableHead className="text-white text-center border-r">
|
||||
Jenis Kegiatan
|
||||
</TableHead>
|
||||
<TableHead className="text-white text-center border-r">
|
||||
Alamat
|
||||
</TableHead>
|
||||
<TableHead className="text-white text-center border-r">
|
||||
Telepon / Fax
|
||||
</TableHead>
|
||||
<TableHead className="text-white text-center border-r">
|
||||
Email
|
||||
</TableHead>
|
||||
<TableHead className="text-white text-center border-r">
|
||||
Jenis Izin
|
||||
</TableHead>
|
||||
<TableHead className="text-white text-center border-r">
|
||||
Nomor Izin
|
||||
</TableHead>
|
||||
<TableHead className="text-white text-center border-r">
|
||||
Tanggal Izin
|
||||
</TableHead>
|
||||
<TableHead className="text-white text-center border-r">
|
||||
Dok
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{filteredPerusahaan.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={9}
|
||||
className="text-center py-4"
|
||||
>
|
||||
Tidak ada data
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
filteredPerusahaan.map((p, index) => (
|
||||
<TableRow
|
||||
key={p.PerusahaanId}
|
||||
className="border-b"
|
||||
>
|
||||
<TableCell className="text-center border-r">
|
||||
{index + 1}
|
||||
</TableCell>
|
||||
<TableCell className="border-r">
|
||||
{p.NamaPerusahaan || "N/A"}
|
||||
</TableCell>
|
||||
<TableCell className="text-center border-r">
|
||||
{p.jenis_kegiatan?.NamaJenisKegiatan ||
|
||||
"N/A"}
|
||||
</TableCell>
|
||||
<TableCell className="text-center border-r">
|
||||
{p.Alamat || "N/A"}
|
||||
</TableCell>
|
||||
<TableCell className="text-center border-r">
|
||||
{p.Telepon || "N/A"} / {p.Fax || "N/A"}
|
||||
</TableCell>
|
||||
<TableCell className="text-center border-r">
|
||||
{p.Email || "N/A"}
|
||||
</TableCell>
|
||||
{/* <TableCell className="text-center border-r">
|
||||
{p.jenis_dok_i_l?.NamaJenisDokIL ||
|
||||
"N/A"}
|
||||
</TableCell> */}
|
||||
<TableCell className="border-r text-center">
|
||||
<button
|
||||
className="text-blue-600 hover:underline"
|
||||
onClick={() =>
|
||||
handleJenisIzinClick(p)
|
||||
}
|
||||
>
|
||||
{p.jenis_dok_i_l?.NamaJenisDokIL ??
|
||||
"Klik di sini"}
|
||||
</button>
|
||||
</TableCell>
|
||||
<TableCell className="text-center border-r">
|
||||
{p.ILNomor || "-"}
|
||||
</TableCell>
|
||||
<TableCell className="text-center border-r">
|
||||
{p.ILTanggal
|
||||
? new Date(
|
||||
p.ILTanggal
|
||||
).toLocaleDateString("en-GB")
|
||||
: "-"}
|
||||
</TableCell>
|
||||
<TableCell className="text-center border-r">
|
||||
{p.ILDokumen ? (
|
||||
<a
|
||||
href={`/storage/${p.ILDokumen}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-center"
|
||||
>
|
||||
<FileText className="w-4 h-4 text-green-600 hover:text-green-800" />
|
||||
</a>
|
||||
) : (
|
||||
"-"
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</AuthenticatedLayout>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue