skl/resources/js/pages/admin/pelaporan/AL/ALForm.tsx

467 lines
21 KiB
TypeScript

import React, { useState, useEffect } from "react";
import { Head, router } from "@inertiajs/react";
import AuthenticatedLayout from "@/layouts/authenticated-layout";
import { Card, CardHeader, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import {
ChevronLeft,
Printer,
FileDown,
ArrowUpRight,
Save,
} from "lucide-react";
import axios from "axios";
// Import components
import ALTable from "@/components/AL/ALTable";
import LampiranModal from "@/components/AL/LampiranModal";
import SplModal from "@/components/AL/SplModal";
interface PelaporanALProps {
idmcpelaporan: number;
nama_perusahaan: string;
tahun: number;
periode: string;
editable: boolean;
ipal_komunal: string;
lampiran_sk: number;
verifikasi_sk: string | null;
ket_sk: string | null;
catatan: string;
// Table data props
data_table: Record<string, any>;
nilai_komponen: Record<string, any>;
nilai_syarat_teknis: Record<string, number>;
nilai_A6: number;
nilai_A7: number;
idrefpelaporan: number;
rowspan_1: number;
spl: number;
spl_2: number;
}
const ALForm: React.FC<PelaporanALProps> = (props) => {
const [ipalKomunal, setIpalKomunal] = useState<string>(props.ipal_komunal);
const [lampiranSK, setLampiranSK] = useState<number>(props.lampiran_sk);
const [catatan, setCatatan] = useState<string>(props.catatan);
const [showSkFields, setShowSkFields] = useState<boolean>(
props.ipal_komunal === "Iya"
);
const [agreement, setAgreement] = useState<boolean>(false);
// Modals state
const [lampiranModalOpen, setLampiranModalOpen] = useState<boolean>(false);
const [selectedKomponen, setSelectedKomponen] = useState<string>("");
const [selectedIdRefKomponen, setSelectedIdRefKomponen] =
useState<number>(0);
const [splModalOpen, setSplModalOpen] = useState<boolean>(false);
// Table related states
const [dataTable, setDataTable] = useState(props.data_table);
const [nilaiKomponen, setNilaiKomponen] = useState(props.nilai_komponen);
useEffect(() => {
// Check for lampiran SK on component mount
if (ipalKomunal === "Iya") {
checkLampiranSK();
}
}, []);
const checkLampiranSK = async () => {
try {
const response = await axios.get(
`/pelaporan/al/cek-surat-kerjasama/${props.idmcpelaporan}`
);
if (response.data.lampiran && ipalKomunal === "Iya") {
setLampiranSK(1);
// If connected to communal IPAL and attachment exists, disable all fields
disableLampiran();
changeNilai();
} else {
setLampiranSK(0);
}
} catch (error) {
console.error("Error checking SK:", error);
}
};
const handleIpalKomunalChange = (value: string) => {
setIpalKomunal(value);
setShowSkFields(value === "Iya");
if (value === "Tidak") {
// Enable all inputs if not connected to communal IPAL
enableLampiran();
} else {
if (lampiranSK) {
// If connected to communal IPAL and attachment exists, disable all fields
disableLampiran();
changeNilai();
}
}
};
const disableLampiran = () => {
// This function would disable all lampiran links in UI
// In React we handle this through state/props rather than direct DOM manipulation
};
const enableLampiran = () => {
// This function would enable all lampiran links in UI
// In React we handle this through state/props rather than direct DOM manipulation
};
const changeNilai = () => {
// If SK is verified and not rejected, set all values to 100
// If rejected, set all to 0
const newNilaiKomponen = { ...nilaiKomponen };
const nilai = props.verifikasi_sk === "Not Approved" ? 0 : 100;
// Update all nilai komponen
Object.keys(newNilaiKomponen).forEach((key) => {
if (newNilaiKomponen[key]) {
newNilaiKomponen[key].nilai = nilai;
}
});
setNilaiKomponen(newNilaiKomponen);
};
const handleUpdateNilai = (kode: string, nilai: number) => {
const newNilaiKomponen = { ...nilaiKomponen };
if (newNilaiKomponen[kode]) {
newNilaiKomponen[kode].nilai = nilai;
} else {
newNilaiKomponen[kode] = { nilai };
}
setNilaiKomponen(newNilaiKomponen);
};
const handleOpenLampiranModal = (kode: string, idrefkomponen: number) => {
setSelectedKomponen(kode);
setSelectedIdRefKomponen(idrefkomponen);
setLampiranModalOpen(true);
};
const handleOpenSplModal = () => {
setSplModalOpen(true);
};
const handleSubmit = () => {
// Handle form submission - save and send report
if (ipalKomunal === "Iya" && lampiranSK === 0) {
alert("Silahkan Upload Lampiran Surat Kerjasama terlebih dahulu");
return;
}
// Prepare data
const formData = {
ipal_komunal: ipalKomunal,
catatan: catatan,
nilai_komponen: nilaiKomponen,
send: true,
};
// Submit data
router.post(`/pelaporan/al/simpan/${props.idmcpelaporan}`, formData);
};
const handleSaveDraft = () => {
// Save form as draft
if (ipalKomunal === "Iya" && lampiranSK === 0) {
alert("Silahkan Upload Lampiran Surat Kerjasama terlebih dahulu");
return;
}
// Prepare data
const formData = {
ipal_komunal: ipalKomunal,
catatan: catatan,
nilai_komponen: nilaiKomponen,
send: false,
};
// Submit data
router.post(`/pelaporan/al/simpan/${props.idmcpelaporan}`, formData);
};
const handlePrint = () => {
window.print();
};
const handleExport = () => {
window.location.href = `/pelaporan/al/export-pdf/${props.idmcpelaporan}`;
};
return (
<AuthenticatedLayout header="Pelaporan Air Limbah">
<Head title="Pelaporan Air Limbah" />
<div className="p-4 space-y-6">
<Card className="shadow-lg border-none">
<CardHeader className="bg-gradient-to-r from-green-800 to-green-700 text-white rounded-t-lg">
<div className="flex justify-between items-center">
<div>
<h1 className="text-xl font-bold">
Laporan Pengelolaan Air Limbah
</h1>
<p>{props.nama_perusahaan}</p>
<p>
Tahun {props.tahun} - Periode{" "}
{props.periode}
</p>
</div>
<div className="flex gap-2">
<Button
variant="secondary"
size="sm"
onClick={handlePrint}
>
<Printer className="h-4 w-4" />
</Button>
<Button
variant="secondary"
size="sm"
onClick={handleExport}
>
<FileDown className="h-4 w-4" />
</Button>
<Button
variant="secondary"
size="sm"
onClick={() =>
router.get("/pelaporan", {
save_search: 1,
})
}
>
<ChevronLeft className="h-4 w-4" />
</Button>
</div>
</div>
</CardHeader>
<CardContent className="p-6">
<form id="al-form">
{/* IPAL Komunal Section */}
<div className="flex flex-wrap mb-6 border p-4 rounded-lg bg-gray-50">
<div
className={`${
showSkFields ? "w-1/4" : "w-full"
}`}
>
<Label className="font-medium mb-2 block">
Tersambung ke IPAL Komunal:
</Label>
<div className="space-x-4">
<label className="inline-flex items-center">
<input
type="radio"
name="ipal_komunal"
value="Iya"
checked={ipalKomunal === "Iya"}
onChange={(e) =>
handleIpalKomunalChange(
e.target.value
)
}
disabled={!props.editable}
className="form-radio text-green-600"
/>
<span className="ml-2">Iya</span>
</label>
<label className="inline-flex items-center">
<input
type="radio"
name="ipal_komunal"
value="Tidak"
checked={
ipalKomunal === "Tidak"
}
onChange={(e) =>
handleIpalKomunalChange(
e.target.value
)
}
disabled={!props.editable}
className="form-radio text-green-600"
/>
<span className="ml-2">Tidak</span>
</label>
</div>
</div>
{showSkFields && (
<>
<div className="w-1/4">
<Label className="font-medium mb-2 block">
Lampiran:
</Label>
<button
type="button"
onClick={() =>
handleOpenLampiranModal(
"SK",
0
)
}
disabled={!props.editable}
className="text-blue-600 hover:text-blue-800 hover:underline"
>
Surat Kerjasama
</button>
</div>
{props.verifikasi_sk && (
<>
<div className="w-1/4">
<Label className="font-medium mb-2 block">
Verifikasi:
</Label>
<span
className={
props.verifikasi_sk ===
"Approved"
? "text-green-600"
: "text-red-600"
}
>
{props.verifikasi_sk}
</span>
</div>
<div className="w-1/4">
<Label className="font-medium mb-2 block">
Keterangan:
</Label>
<p className="text-sm">
{props.ket_sk}
</p>
</div>
</>
)}
</>
)}
</div>
{/* Main Table */}
<div className="border rounded-lg overflow-x-auto shadow-sm mb-6">
<ALTable
dataTable={dataTable}
nilaiKomponen={nilaiKomponen}
nilaiSyaratTeknis={
props.nilai_syarat_teknis
}
nilai_A6={props.nilai_A6}
nilai_A7={props.nilai_A7}
idmcpelaporan={props.idmcpelaporan}
idrefpelaporan={props.idrefpelaporan}
rowspan_1={props.rowspan_1}
spl={props.spl}
spl_2={props.spl_2}
editable={props.editable}
onUpdateNilai={handleUpdateNilai}
onOpenLampiranModal={
handleOpenLampiranModal
}
onOpenSplModal={handleOpenSplModal}
/>
</div>
{/* Notes Section */}
<div className="mb-6">
<Label className="font-medium mb-2 block">
Catatan:
</Label>
<Textarea
value={catatan}
onChange={(e) => setCatatan(e.target.value)}
disabled={!props.editable}
className="min-h-[100px] bg-white border-gray-300 focus:border-green-500 focus:ring-green-500"
/>
</div>
{/* Submit buttons */}
{props.editable && (
<>
<div className="flex items-start gap-3 p-4 bg-green-50 rounded-lg border border-green-200 mb-6">
<Checkbox
id="agreement"
checked={agreement}
onCheckedChange={(checked) =>
setAgreement(checked as boolean)
}
className="mt-1 text-green-600 focus:ring-green-500"
/>
<div>
<Label
htmlFor="agreement"
className="text-sm font-medium text-gray-800"
>
Pernyataan Kebenaran Data
</Label>
<p className="text-sm leading-relaxed text-gray-700 mt-1">
Kami menyatakan bahwa laporan
ini telah disusun berdasarkan
ketentuan peraturan yang berlaku
dan kami bersedia bertanggung
jawab atas kebenaran data-data
yang kami kirimkan sesuai dengan
fakta dilapangan.
</p>
</div>
</div>
<div className="flex justify-end gap-4">
<Button
variant="outline"
className="hover:bg-gray-100 gap-2"
onClick={handleSaveDraft}
>
<Save className="h-4 w-4" />
Simpan Draft
</Button>
<Button
className="bg-green-800 hover:bg-green-700 transition-colors px-8 gap-2"
onClick={handleSubmit}
disabled={!agreement}
>
<ArrowUpRight className="h-4 w-4" />
Kirim Laporan
</Button>
</div>
</>
)}
</form>
</CardContent>
</Card>
</div>
{/* Modals */}
<LampiranModal
isOpen={lampiranModalOpen}
onClose={() => {
setLampiranModalOpen(false);
if (selectedKomponen === "SK") {
checkLampiranSK();
}
}}
idMcIpal={0} // For SK this needs to be handled differently
kodeKomponen={selectedKomponen}
namaKomponen={
selectedKomponen === "SK" ? "Surat Kerjasama" : ""
}
editable={props.editable}
/>
<SplModal
isOpen={splModalOpen}
onClose={() => setSplModalOpen(false)}
idMcPelaporan={props.idmcpelaporan}
/>
</AuthenticatedLayout>
);
};
export default ALForm;