feat: Tambahkan komponen FilterPencarian dan ModalIzinLingkungan
parent
4c21af6209
commit
3c71e9289c
|
@ -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<DateRange | undefined>({
|
||||
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<SelectOption | null>(null);
|
||||
const [selectedJenisKegiatan, setSelectedJenisKegiatan] =
|
||||
useState<SelectOption | null>(null);
|
||||
const [Alamat, setAlamat] = useState<string>("");
|
||||
const [TeleponFax, setTeleponFax] = useState<string>("");
|
||||
const [Email, setEmail] = useState<string>("");
|
||||
const [selectedJenisIzin, setSelectedJenisIzin] =
|
||||
useState<SelectOption | null>(null);
|
||||
const [ILNomor, setILNomor] = useState<string>("");
|
||||
const [ILTanggal, setILTanggal] = useState<Date | null>(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 (
|
||||
<div className="bg-white py-6 rounded-lg shadow-sm mb-6">
|
||||
<Card className="shadow-md border-slate-200">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-lg font-medium">
|
||||
Filter Pencarian Perizinan Lingkungan
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
{/* Kolom Kiri */}
|
||||
<div className="space-y-4">
|
||||
<div className="grid grid-cols-3 items-center gap-4">
|
||||
<label className="text-sm font-medium text-gray-700">
|
||||
Nama Perusahaan
|
||||
</label>
|
||||
<div className="col-span-2">
|
||||
<Select
|
||||
options={perusahaanOptions}
|
||||
value={selectedPerusahaan}
|
||||
onChange={setSelectedPerusahaan}
|
||||
placeholder="Pilih Perusahaan"
|
||||
isClearable
|
||||
isSearchable
|
||||
styles={selectStyles}
|
||||
noOptionsMessage={() =>
|
||||
"Tidak ada data"
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 items-center gap-4">
|
||||
<label className="text-sm font-medium text-gray-700">
|
||||
Jenis Kegiatan
|
||||
</label>
|
||||
<div className="col-span-2">
|
||||
<Select
|
||||
options={jenisKegiatanOptions}
|
||||
value={selectedJenisKegiatan}
|
||||
onChange={setSelectedJenisKegiatan}
|
||||
placeholder="Pilih Jenis Kegiatan"
|
||||
isClearable
|
||||
isSearchable
|
||||
styles={selectStyles}
|
||||
noOptionsMessage={() =>
|
||||
"Tidak ada data"
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 items-center gap-4">
|
||||
<label className="text-sm font-medium text-gray-700">
|
||||
Alamat
|
||||
</label>
|
||||
<div className="col-span-2">
|
||||
<Input
|
||||
placeholder="Masukkan Alamat"
|
||||
value={Alamat}
|
||||
onChange={(e) =>
|
||||
setAlamat(e.target.value)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 items-center gap-4">
|
||||
<label className="text-sm font-medium text-gray-700">
|
||||
Telepon/Fax
|
||||
</label>
|
||||
<div className="col-span-2">
|
||||
<Input
|
||||
placeholder="Masukkan Telepon/Fax"
|
||||
value={TeleponFax}
|
||||
onChange={(e) =>
|
||||
setTeleponFax(e.target.value)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Kolom Kanan */}
|
||||
<div className="space-y-4">
|
||||
<div className="grid grid-cols-3 items-center gap-4">
|
||||
<label className="text-sm font-medium text-gray-700">
|
||||
Email
|
||||
</label>
|
||||
<div className="col-span-2">
|
||||
<Input
|
||||
placeholder="Masukkan Email"
|
||||
value={Email}
|
||||
onChange={(e) =>
|
||||
setEmail(e.target.value)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 items-center gap-4">
|
||||
<label className="text-sm font-medium text-gray-700">
|
||||
Jenis Izin
|
||||
</label>
|
||||
<div className="col-span-2">
|
||||
<Select
|
||||
options={jenisIzinOptions}
|
||||
value={selectedJenisIzin}
|
||||
onChange={setSelectedJenisIzin}
|
||||
placeholder="Pilih Jenis Izin"
|
||||
isClearable
|
||||
isSearchable
|
||||
styles={selectStyles}
|
||||
noOptionsMessage={() =>
|
||||
"Tidak ada data"
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 items-center gap-4">
|
||||
<label className="text-sm font-medium text-gray-700">
|
||||
Nomor Izin
|
||||
</label>
|
||||
<div className="col-span-2">
|
||||
<Input
|
||||
placeholder="Masukkan Nomor Izin"
|
||||
value={ILNomor}
|
||||
onChange={(e) =>
|
||||
setILNomor(e.target.value)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 items-center gap-4">
|
||||
<label className="text-sm font-medium text-gray-700">
|
||||
Rentang Tanggal Izin
|
||||
</label>
|
||||
<div className="col-span-2">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="w-full text-left"
|
||||
>
|
||||
<CalendarIcon className="mr-2 h-4 w-4" />
|
||||
{dateRange?.from
|
||||
? dateRange.to
|
||||
? `${format(
|
||||
dateRange.from,
|
||||
"dd/MM/yyyy"
|
||||
)} - ${format(
|
||||
dateRange.to,
|
||||
"dd/MM/yyyy"
|
||||
)}`
|
||||
: format(
|
||||
dateRange.from,
|
||||
"dd/MM/yyyy"
|
||||
)
|
||||
: "Pilih Rentang Tanggal"}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
className="w-auto p-0"
|
||||
align="start"
|
||||
>
|
||||
<UIDatePicker
|
||||
initialFocus
|
||||
mode="range"
|
||||
defaultMonth={dateRange?.from}
|
||||
selected={dateRange}
|
||||
onSelect={setDateRange}
|
||||
numberOfMonths={2}
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-end mt-6 gap-2">
|
||||
<Button
|
||||
className="bg-green-600 hover:bg-green-700 text-white"
|
||||
onClick={handleSearch}
|
||||
>
|
||||
<Search className="w-4 h-4 mr-2" />
|
||||
Cari
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-gray-600 hover:bg-gray-700 text-white"
|
||||
onClick={handleReset}
|
||||
>
|
||||
Reset
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -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<File | null>(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 (
|
||||
<Dialog open={open} onOpenChange={onClose}>
|
||||
<DialogContent className="max-w-xl max-h-[85vh] overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Perizinan Lingkungan</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
{/* Detail perusahaan */}
|
||||
<div className="mb-4 p-4 bg-blue-100 rounded-md border border-gray-200">
|
||||
<div className="grid grid-cols-2 gap-2 text-sm">
|
||||
<div className="font-bold">No Induk:</div>
|
||||
<div>{selectedPerusahaan.NomorInduk || "-"}</div>
|
||||
|
||||
<div className="font-bold">Perusahaan:</div>
|
||||
<div>{selectedPerusahaan.NamaPerusahaan || "-"}</div>
|
||||
|
||||
<div className="font-bold">Jenis Kegiatan:</div>
|
||||
<div>
|
||||
{selectedPerusahaan.jenis_kegiatan
|
||||
?.NamaJenisKegiatan || "-"}
|
||||
</div>
|
||||
|
||||
<div className="font-bold">Alamat:</div>
|
||||
<div>{selectedPerusahaan.Alamat || "-"}</div>
|
||||
|
||||
<div className="font-bold">Telepon:</div>
|
||||
<div>{selectedPerusahaan.Telepon || "-"}</div>
|
||||
|
||||
<div className="font-bold">Fax:</div>
|
||||
<div>{selectedPerusahaan.Fax || "-"}</div>
|
||||
|
||||
<div className="font-bold">Email:</div>
|
||||
<div>{selectedPerusahaan.Email || "-"}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Form update dokumen izin */}
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<label className="block text-sm font-medium text-gray-700">
|
||||
Nomor Izin Lingkungan
|
||||
</label>
|
||||
<Input
|
||||
type="text"
|
||||
value={nomorIzin}
|
||||
onChange={(e) => setNomorIzin(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="block text-sm font-medium text-gray-700">
|
||||
Tanggal Izin
|
||||
</label>
|
||||
<Input
|
||||
type="date"
|
||||
value={tanggalIzin}
|
||||
onChange={(e) => setTanggalIzin(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="block text-sm font-medium text-gray-700">
|
||||
Jenis Kegiatan
|
||||
</label>
|
||||
<Select
|
||||
options={jenisKegiatanOptions}
|
||||
value={selectedJenisKegiatan}
|
||||
onChange={setSelectedJenisKegiatan}
|
||||
placeholder="Pilih Jenis Kegiatan"
|
||||
isClearable
|
||||
isSearchable
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="block text-sm font-medium text-gray-700">
|
||||
Upload Dokumen
|
||||
</label>
|
||||
<Input
|
||||
type="file"
|
||||
onChange={(e) => {
|
||||
if (
|
||||
e.target.files &&
|
||||
e.target.files.length > 0
|
||||
) {
|
||||
setDokumen(e.target.files[0]);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{selectedPerusahaan.ILDokumen && (
|
||||
<div className="mb-4">
|
||||
<Button
|
||||
className="bg-green-100"
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() =>
|
||||
window.open(
|
||||
`/storage/${selectedPerusahaan.ILDokumen}`,
|
||||
"_blank"
|
||||
)
|
||||
}
|
||||
>
|
||||
Lihat File saat ini
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex justify-end mt-6">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={onClose}
|
||||
className="mr-2"
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
className="bg-green-600 text-white"
|
||||
>
|
||||
Simpan
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
import React from "react";
|
||||
import { Link } from "@inertiajs/react";
|
||||
|
||||
const Pagination = ({ links }) => {
|
||||
return (
|
||||
<nav
|
||||
className="mb-sm-0 d-flex justify-content-center"
|
||||
aria-label="navigation"
|
||||
>
|
||||
<ul className="pagination pagination-md pagination-primary-soft mb-0">
|
||||
{/* Loop through the pagination links */}
|
||||
{links.map((link, index) => (
|
||||
<li
|
||||
key={index}
|
||||
className={`page-item ${link.active ? "active" : ""} ${
|
||||
!link.url ? "disabled" : ""
|
||||
}`}
|
||||
>
|
||||
<Link
|
||||
href={link.url || "#"}
|
||||
className="page-link"
|
||||
tabIndex={!link.url ? "-1" : "0"}
|
||||
dangerouslySetInnerHTML={{ __html: link.label }}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
export default Pagination;
|
|
@ -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() {
|
|||
|
||||
<div className="p-8">
|
||||
{/* Filter Section */}
|
||||
<div className="mb-6 space-y-4">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex gap-4 items-center">
|
||||
<Select
|
||||
options={companyOptions}
|
||||
value={company}
|
||||
onChange={setCompany}
|
||||
placeholder="Pilih Perusahaan"
|
||||
isSearchable
|
||||
className="w-[300px]"
|
||||
/>
|
||||
<div className="bg-white rounded-lg shadow-sm mb-6">
|
||||
<Card className="shadow-md border-slate-200 justify-between">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-lg font-medium">
|
||||
Pelaporan SKL
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="flex flex-col md:flex-row md:justify-between md:items-center gap-4">
|
||||
<div className="flex flex-col sm:flex-row gap-4 items-start sm:items-center w-full">
|
||||
<Select
|
||||
options={companyOptions}
|
||||
value={company}
|
||||
onChange={setCompany}
|
||||
placeholder="Pilih Perusahaan"
|
||||
isSearchable
|
||||
className="w-full sm:w-[300px]"
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="number"
|
||||
value={year}
|
||||
onChange={(e) => setYear(e.target.value)}
|
||||
className="w-24"
|
||||
/>
|
||||
<div className="flex gap-4 w-full sm:w-auto">
|
||||
<Input
|
||||
type="number"
|
||||
value={year}
|
||||
onChange={(e) =>
|
||||
setYear(e.target.value)
|
||||
}
|
||||
className="w-full sm:w-24"
|
||||
/>
|
||||
|
||||
<Select
|
||||
options={[
|
||||
{
|
||||
value: "Triwulan 1",
|
||||
label: "Triwulan 1",
|
||||
},
|
||||
{
|
||||
value: "Triwulan 2",
|
||||
label: "Triwulan 2",
|
||||
},
|
||||
{
|
||||
value: "Triwulan 3",
|
||||
label: "Triwulan 3",
|
||||
},
|
||||
{
|
||||
value: "Triwulan 4",
|
||||
label: "Triwulan 4",
|
||||
},
|
||||
]}
|
||||
value={{ value: quarter, label: quarter }}
|
||||
onChange={(newValue) =>
|
||||
setQuarter(newValue?.value || "Triwulan 1")
|
||||
}
|
||||
placeholder="Pilih Periode"
|
||||
className="w-[150px]"
|
||||
/>
|
||||
<Select
|
||||
options={[
|
||||
{
|
||||
value: "Triwulan 1",
|
||||
label: "Triwulan 1",
|
||||
},
|
||||
{
|
||||
value: "Triwulan 2",
|
||||
label: "Triwulan 2",
|
||||
},
|
||||
{
|
||||
value: "Triwulan 3",
|
||||
label: "Triwulan 3",
|
||||
},
|
||||
{
|
||||
value: "Triwulan 4",
|
||||
label: "Triwulan 4",
|
||||
},
|
||||
]}
|
||||
value={{
|
||||
value: quarter,
|
||||
label: quarter,
|
||||
}}
|
||||
onChange={(newValue) =>
|
||||
setQuarter(
|
||||
newValue?.value ||
|
||||
"Triwulan 1"
|
||||
)
|
||||
}
|
||||
placeholder="Pilih Periode"
|
||||
className="w-full sm:w-[150px]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button>
|
||||
<Search className="w-4 h-4 mr-2" />
|
||||
Cari
|
||||
</Button>
|
||||
</div>
|
||||
<Button className="w-full sm:w-auto">
|
||||
<Search className="w-4 h-4 mr-2" />
|
||||
Cari
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* <div className="flex gap-2">
|
||||
{/* <div className="flex gap-2">
|
||||
<Button variant="outline">
|
||||
<Upload className="w-4 h-4 mr-2" />
|
||||
Import
|
||||
|
@ -153,7 +171,9 @@ export default function PelaporanIndex() {
|
|||
Template
|
||||
</Button>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Table Section */}
|
||||
|
@ -284,14 +304,14 @@ export default function PelaporanIndex() {
|
|||
</TableCell>
|
||||
<TableCell
|
||||
colSpan={1}
|
||||
className="text-center text-muted-foreground border-r border-l bg-red-100 text-red-700"
|
||||
className="text-center hover:underline text-muted-foreground border-r border-l bg-red-100 text-red-700"
|
||||
>
|
||||
00.00
|
||||
</TableCell>
|
||||
|
||||
<TableCell
|
||||
colSpan={1}
|
||||
className="text-center text-muted-foreground border-r border-l bg-red-100 text-red-700"
|
||||
className="text-center hover:underline text-muted-foreground border-r border-l bg-red-100 text-red-700"
|
||||
>
|
||||
<Link href="/admin/pelaporan/al">
|
||||
00.00
|
||||
|
@ -300,37 +320,37 @@ export default function PelaporanIndex() {
|
|||
|
||||
<TableCell
|
||||
colSpan={1}
|
||||
className="text-center text-muted-foreground border-r border-l bg-red-100 text-red-700"
|
||||
className="text-center hover:underline text-muted-foreground border-r border-l bg-red-100 text-red-700"
|
||||
>
|
||||
00.00
|
||||
</TableCell>
|
||||
<TableCell
|
||||
colSpan={1}
|
||||
className="text-center text-muted-foreground border-r border-l bg-gray-100 text-gray-700"
|
||||
className="text-center hover:underline text-muted-foreground border-r border-l bg-gray-100 text-gray-700"
|
||||
>
|
||||
76.70
|
||||
</TableCell>
|
||||
<TableCell
|
||||
colSpan={1}
|
||||
className="text-center text-muted-foreground border-r border-l bg-gray-100 text-gray-700"
|
||||
className="text-center hover:underline text-muted-foreground border-r border-l bg-gray-100 text-gray-700"
|
||||
>
|
||||
76.70
|
||||
</TableCell>
|
||||
<TableCell
|
||||
colSpan={1}
|
||||
className="text-center text-muted-foreground border-r border-l bg-orange-100 text-orange-700"
|
||||
className="text-center hover:underline text-muted-foreground border-r border-l bg-orange-100 text-orange-700"
|
||||
>
|
||||
76.70
|
||||
</TableCell>
|
||||
<TableCell
|
||||
colSpan={1}
|
||||
className="text-center text-muted-foreground border-r border-l bg-green-100 text-green-700"
|
||||
className="text-center hover:underline text-muted-foreground border-r border-l bg-green-100 text-green-700"
|
||||
>
|
||||
76.70
|
||||
</TableCell>
|
||||
<TableCell
|
||||
colSpan={1}
|
||||
className="text-center text-muted-foreground border-r border-l bg-green-100 text-green-700"
|
||||
className="text-center hover:underline text-muted-foreground border-r border-l bg-green-100 text-green-700"
|
||||
>
|
||||
76.70
|
||||
</TableCell>
|
||||
|
@ -362,69 +382,69 @@ export default function PelaporanIndex() {
|
|||
</div> */}
|
||||
|
||||
{/* Legend Section */}
|
||||
<div className="mt-6 grid grid-cols-2 gap-6">
|
||||
<div className="mt-6 flex flex-col md:grid md:grid-cols-2 gap-6">
|
||||
{/* Keterangan Section */}
|
||||
<div className="bg-white rounded-lg shadow-sm border p-6">
|
||||
<div className="bg-white rounded-lg shadow-sm border p-4 md:p-6">
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<FileText className="w-5 h-5 text-green-600" />
|
||||
<h3 className="font-semibold text-lg">
|
||||
Keterangan
|
||||
</h3>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<div className="min-w-[8px] w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<p className="text-sm">
|
||||
SKL : Status Ketaatan Lingkungan
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<div className="min-w-[8px] w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<p className="text-sm">
|
||||
SPBM : Status Pemenuhan Baku Mutu
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<div className="min-w-[8px] w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<p className="text-sm">
|
||||
IL : Ijin Lingkungan
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<div className="min-w-[8px] w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<p className="text-sm">AL : Air Limbah</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<div className="min-w-[8px] w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<p className="text-sm">LB3 : Limbah B3</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<div className="min-w-[8px] w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<p className="text-sm">
|
||||
SB : Sumber Bergerak
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<div className="min-w-[8px] w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<p className="text-sm">
|
||||
BS : Kebisingan & Udara Ambien
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<div className="min-w-[8px] w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<p className="text-sm">
|
||||
STB : Sumber Tidak Bergerak
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<div className="min-w-[8px] w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<p className="text-sm">LP : Limbah Padat</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<div className="min-w-[8px] w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<p className="text-sm">
|
||||
KDM : Kawasan Dilarang Merokok
|
||||
</p>
|
||||
|
@ -432,15 +452,15 @@ export default function PelaporanIndex() {
|
|||
</div>
|
||||
<div className="space-y-2 pt-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<div className="min-w-[8px] w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<p className="text-sm">
|
||||
STT : Surat Tanda Terima
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2 pt-3">
|
||||
<div className="space-y-2 pt-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<div className="min-w-[8px] w-2 h-2 rounded-full bg-green-500"></div>
|
||||
<p className="text-sm">
|
||||
SE : Surat Evaluasi
|
||||
</p>
|
||||
|
@ -450,34 +470,34 @@ export default function PelaporanIndex() {
|
|||
</div>
|
||||
|
||||
{/* Status Data Section */}
|
||||
<div className="bg-white rounded-lg shadow-sm border p-6">
|
||||
<div className="bg-white rounded-lg shadow-sm border p-4 md:p-6 mt-4 md:mt-0">
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<BadgeCheck className="w-5 h-5 text-green-600" />
|
||||
<h3 className="font-semibold text-lg">
|
||||
Status Data
|
||||
</h3>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center gap-3 p-2 rounded-md bg-red-100">
|
||||
<div className="w-3 h-3 rounded-full bg-red-500"></div>
|
||||
<div className="min-w-[12px] w-3 h-3 rounded-full bg-red-500"></div>
|
||||
<p className="text-sm text-red-700">
|
||||
Data belum diisi
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 p-2 rounded-md bg-gray-100">
|
||||
<div className="w-3 h-3 rounded-full bg-gray-500"></div>
|
||||
<div className="min-w-[12px] w-3 h-3 rounded-full bg-gray-500"></div>
|
||||
<p className="text-sm text-gray-700">
|
||||
Data telah diisi dan belum diverifikasi
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 p-2 rounded-md bg-orange-100">
|
||||
<div className="w-3 h-3 rounded-full bg-orange-500"></div>
|
||||
<div className="min-w-[12px] w-3 h-3 rounded-full bg-orange-500"></div>
|
||||
<p className="text-sm text-orange-700">
|
||||
Data telah siap untuk diverifikasi
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 p-2 rounded-md bg-green-100">
|
||||
<div className="w-3 h-3 rounded-full bg-green-500"></div>
|
||||
<div className="min-w-[12px] w-3 h-3 rounded-full bg-green-500"></div>
|
||||
<p className="text-sm text-green-700">
|
||||
Data telah diisi dan diverifikasi
|
||||
</p>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
use App\Http\Controllers\Admin\RoleController;
|
||||
use App\Http\Controllers\Admin\RolesController;
|
||||
use App\Http\Controllers\CategoryController;
|
||||
use App\Http\Controllers\DaftarPerusahaanController;
|
||||
use App\Http\Controllers\HistoryKegiatanController;
|
||||
|
@ -34,6 +36,9 @@ use Illuminate\Foundation\Application;
|
|||
use Illuminate\Support\Facades\Route;
|
||||
use Inertia\Inertia;
|
||||
use Illuminate\Http\Response;
|
||||
use Spatie\Permission\Middleware\PermissionMiddleware;
|
||||
use App\Http\Controllers\Admin\DashboardController;
|
||||
use App\Http\Controllers\PerizinanLingkunganController;
|
||||
|
||||
Route::get('/', [HomeController::class, 'index'])->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';
|
||||
|
|
Loading…
Reference in New Issue