194 lines
9.0 KiB
TypeScript
194 lines
9.0 KiB
TypeScript
import React, { useState, useEffect } from "react";
|
|
import { Button } from "@/components/ui/button";
|
|
import { X, Info } from "lucide-react";
|
|
import axios from "axios";
|
|
|
|
interface SplModalProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
idMcPelaporan: number;
|
|
}
|
|
|
|
interface SplData {
|
|
nilai: number;
|
|
keterangan: string;
|
|
detail: {
|
|
nama_ipal: string;
|
|
parameter: string;
|
|
baku_mutu: number;
|
|
hasil_uji: number;
|
|
keterangan: string;
|
|
}[];
|
|
}
|
|
|
|
const SplModal: React.FC<SplModalProps> = ({
|
|
isOpen,
|
|
onClose,
|
|
idMcPelaporan,
|
|
}) => {
|
|
const [splData, setSplData] = useState<SplData | null>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
if (isOpen) {
|
|
loadSplData();
|
|
}
|
|
}, [isOpen, idMcPelaporan]);
|
|
|
|
const loadSplData = async () => {
|
|
setLoading(true);
|
|
try {
|
|
const response = await axios.get(
|
|
`/pelaporan/al/spl/${idMcPelaporan}`
|
|
);
|
|
setSplData(response.data);
|
|
} catch (error) {
|
|
console.error("Error loading SPL data:", error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
if (!isOpen) return null;
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4">
|
|
<div className="bg-white rounded-lg shadow-lg w-full max-w-3xl">
|
|
<div className="p-4 border-b flex justify-between items-center">
|
|
<h2 className="font-semibold text-gray-800 text-lg">
|
|
Nilai Tingkat Pemenuhan Baku Mutu Air Limbah (SPBM
|
|
<sub>AL</sub>)
|
|
</h2>
|
|
<button
|
|
onClick={onClose}
|
|
className="text-gray-500 hover:text-gray-700"
|
|
>
|
|
<X className="w-5 h-5" />
|
|
</button>
|
|
</div>
|
|
|
|
<div className="p-4">
|
|
{loading ? (
|
|
<div className="flex justify-center items-center h-48">
|
|
<div className="animate-spin rounded-full h-10 w-10 border-b-2 border-green-700"></div>
|
|
</div>
|
|
) : splData ? (
|
|
<>
|
|
<div className="mb-6 flex items-center bg-blue-50 p-3 rounded-lg">
|
|
<Info className="h-5 w-5 text-blue-500 mr-2" />
|
|
<p className="text-sm text-blue-700">
|
|
Nilai SPBM<sub>AL</sub> dihitung otomatis
|
|
berdasarkan data hasil uji yang dimasukkan.
|
|
</p>
|
|
</div>
|
|
|
|
<div className="flex justify-between items-center mb-6 bg-green-50 p-4 rounded-lg">
|
|
<h3 className="font-medium text-gray-800">
|
|
Nilai SPBM<sub>AL</sub>:
|
|
</h3>
|
|
<span className="text-2xl font-bold text-green-700">
|
|
{splData.nilai.toFixed(2)}%
|
|
</span>
|
|
</div>
|
|
|
|
<h3 className="font-medium text-gray-800 mb-3">
|
|
Detail Hasil Uji:
|
|
</h3>
|
|
|
|
{splData.detail.length === 0 ? (
|
|
<p className="text-gray-500 text-center py-4">
|
|
Belum ada data hasil uji
|
|
</p>
|
|
) : (
|
|
<div className="overflow-x-auto">
|
|
<table className="w-full border-collapse text-sm">
|
|
<thead>
|
|
<tr className="bg-gray-100">
|
|
<th className="border border-gray-300 p-2">
|
|
IPAL
|
|
</th>
|
|
<th className="border border-gray-300 p-2">
|
|
Parameter
|
|
</th>
|
|
<th className="border border-gray-300 p-2">
|
|
Baku Mutu
|
|
</th>
|
|
<th className="border border-gray-300 p-2">
|
|
Hasil Uji
|
|
</th>
|
|
<th className="border border-gray-300 p-2">
|
|
Keterangan
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{splData.detail.map(
|
|
(item, index) => (
|
|
<tr
|
|
key={index}
|
|
className={
|
|
index % 2 === 0
|
|
? "bg-white"
|
|
: "bg-gray-50"
|
|
}
|
|
>
|
|
<td className="border border-gray-300 p-2">
|
|
{item.nama_ipal}
|
|
</td>
|
|
<td className="border border-gray-300 p-2">
|
|
{item.parameter}
|
|
</td>
|
|
<td className="border border-gray-300 p-2 text-right">
|
|
{item.baku_mutu}
|
|
</td>
|
|
<td className="border border-gray-300 p-2 text-right">
|
|
<span
|
|
className={`font-medium ${
|
|
item.hasil_uji >
|
|
item.baku_mutu
|
|
? "text-red-600"
|
|
: "text-green-600"
|
|
}`}
|
|
>
|
|
{item.hasil_uji}
|
|
</span>
|
|
</td>
|
|
<td className="border border-gray-300 p-2">
|
|
{item.keterangan}
|
|
</td>
|
|
</tr>
|
|
)
|
|
)}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
)}
|
|
|
|
{splData.keterangan && (
|
|
<div className="mt-4">
|
|
<h3 className="font-medium text-gray-800 mb-2">
|
|
Keterangan:
|
|
</h3>
|
|
<p className="text-gray-700 text-sm p-3 bg-gray-50 rounded-lg">
|
|
{splData.keterangan}
|
|
</p>
|
|
</div>
|
|
)}
|
|
</>
|
|
) : (
|
|
<div className="text-center py-8">
|
|
<p className="text-gray-500">Data tidak tersedia</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="p-4 border-t flex justify-end">
|
|
<Button onClick={onClose}>Tutup</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default SplModal;
|