style: Tambahkan beberapa icon baru dan perbaiki tata letak

main
marszayn 2025-03-03 11:52:06 +07:00
parent e37be6bc2d
commit 4ea83cf6b9
1 changed files with 519 additions and 144 deletions

View File

@ -11,7 +11,19 @@ import {
SelectValue,
} from "@/components/ui/select";
import { Checkbox } from "@/components/ui/checkbox";
import { CircleHelp, FileDown, Printer } from "lucide-react";
import {
CircleHelp,
FileDown,
Printer,
ChevronLeft,
Upload,
PlusCircle,
CheckCircle2,
Clock,
AlertCircle,
ArrowUpRight,
Save,
} from "lucide-react";
import AuthenticatedLayout from "@/layouts/authenticated-layout";
import { Head } from "@inertiajs/react";
import { Textarea } from "@/components/ui/textarea";
@ -21,6 +33,7 @@ import {
TooltipTrigger,
} from "@/components/ui/tooltip";
import UploadDoc from "@/components/upload_doc";
import { Badge } from "@/components/ui/badge";
interface PelaporanALFormProps {
onSubmit: (data: any) => void;
@ -31,36 +44,77 @@ const PelaporanALForm = ({ onSubmit }: PelaporanALFormProps) => {
const [isUploadModalOpen, setIsUploadModalOpen] = useState(false);
const [uploadedFile, setUploadedFile] = useState<File | null>(null);
// Mock data for uploaded files/attachments
const [attachments, setAttachments] = useState({
A6: { name: "hasil-uji-lab-q1-2025.pdf", status: "uploaded" },
A7: null,
A8: null,
A9: null,
A10: null,
});
const openAttachmentUpload = (itemCode: string) => {
// Implementation for attachment upload
console.log(`Opening upload for ${itemCode}`);
};
return (
<AuthenticatedLayout header="Pelaporan Air Limbah">
<Head title="Pelaporan Air Limbah" />
<div className="p-4 space-y-6">
<Card className="shadow-lg">
<CardHeader className="bg-[#166534] text-white rounded-t-lg">
<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>
<CardTitle className="text-xl">
Laporan Pengelolaan Air Limbah - Ujicoba
<div className="flex items-center gap-2 mb-1">
<Badge className="bg-green-600">
Nama Perusahaan
</Badge>
</div>
<CardTitle className="text-xl font-bold">
Laporan Pengelolaan Air Limbah
</CardTitle>
<p className="text-sm opacity-90">
Tahun 2025 - Periode Triwulan 1
<p className="text-sm opacity-90 mt-1">
Tahun 2025 - Periode Triwulan 1 (Januari -
Maret)
</p>
</div>
<div className="flex gap-2">
<Button
variant="secondary"
size="sm"
className="gap-1"
onClick={() => window.history.back()}
>
<ChevronLeft className="h-4 w-4" />
Kembali
</Button>
<Button
variant="secondary"
size="sm"
onClick={() => window.print()}
onClick={() => {
const style =
document.createElement("style");
style.innerHTML = `
@media print {
@page {
size: auto;
margin: 20mm;
}
body {
zoom: 0.5;
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
}
`;
document.head.appendChild(style);
window.print();
document.head.removeChild(style);
}}
>
<Printer />
<Printer className="h-4 w-4" />
</Button>
<Button
variant="secondary"
@ -69,31 +123,46 @@ const PelaporanALForm = ({ onSubmit }: PelaporanALFormProps) => {
// Add PDF download logic here
}}
>
<FileDown />
<FileDown className="h-4 w-4" />
</Button>
</div>
</div>
</CardHeader>
<CardContent className="p-6">
<div className="space-y-6">
{/* Header Section */}
<div className="flex justify-between items-center gap-4 mb-6">
<div className="flex items-center gap-2">
<h2>Tersambung IPAL Komunal:</h2>
<div className="flex flex-row gap-3">
{/* Connection Status Card */}
<Card className="border shadow-sm">
<CardContent className="p-4">
<div className="flex flex-wrap lg:flex-nowrap justify-between items-center gap-4">
<div>
<h3 className="font-medium text-gray-900 mb-1">
Status Koneksi IPAL Komunal
</h3>
<p className="text-sm text-gray-500">
Pilih status koneksi instalasi
pengolahan air limbah
</p>
</div>
<div className="flex items-center gap-6">
<div className="flex items-center gap-2">
<input
type="radio"
id="tersambung"
name="connection"
className="w-4 h-4 text-teal-600"
className="w-4 h-4 text-green-600 focus:ring-green-500"
onChange={() =>
setIsConnected(true)
}
checked={isConnected === true}
checked={
isConnected === true
}
/>
<Label htmlFor="tersambung">
Ya
<Label
htmlFor="tersambung"
className="font-medium"
>
Tersambung
</Label>
</div>
<div className="flex items-center gap-2">
@ -101,42 +170,72 @@ const PelaporanALForm = ({ onSubmit }: PelaporanALFormProps) => {
type="radio"
id="tidak"
name="connection"
className="w-4 h-4 text-teal-600"
className="w-4 h-4 text-green-600 focus:ring-green-500"
onChange={() =>
setIsConnected(false)
}
checked={isConnected === false}
checked={
isConnected === false ||
isConnected === null
}
/>
<Label htmlFor="tidak">Tidak</Label>
</div>
<Label
htmlFor="tidak"
className="font-medium"
>
Tidak Tersambung
</Label>
</div>
</div>
<div>
{isConnected && (
<div className="flex items-center gap-2">
<h2>
Lampiran
<span className="text-red-600">
<div className="flex items-center gap-2 bg-green-50 p-3 rounded-lg border border-green-200">
<Upload className="h-4 w-4 text-green-600" />
<span className="text-sm font-medium text-green-800">
Lampiran Wajib
<span className="text-red-600 ml-1">
*
</span>{" "}
</span>
:
</h2>
</span>
<Button
variant="outline"
className="w-48"
size="sm"
className={`ml-2 ${
uploadedFile
? "bg-green-50 text-green-700 border-green-300"
: ""
}`}
onClick={() =>
setIsUploadModalOpen(true)
setIsUploadModalOpen(
true
)
}
>
{uploadedFile
? uploadedFile.name
: "Unggah Surat Kerjasama"}
{uploadedFile ? (
<div className="flex items-center gap-2">
<CheckCircle2 className="h-4 w-4 text-green-600" />
<span className="truncate max-w-36">
{
uploadedFile.name
}
</span>
</div>
) : (
<div className="flex items-center gap-2">
<PlusCircle className="h-4 w-4" />
<span>
Unggah Surat
Kerjasama
</span>
</div>
)}
</Button>
</div>
)}
</div>
</div>
</CardContent>
</Card>
<UploadDoc
isOpen={isUploadModalOpen}
@ -149,10 +248,10 @@ const PelaporanALForm = ({ onSubmit }: PelaporanALFormProps) => {
/>
{/* Main Form Table */}
<div className="border rounded-lg overflow-hidden">
<div className="border rounded-lg overflow-hidden shadow-sm">
<table className="w-full">
<thead>
<tr className="bg-[#166534] text-white">
<tr className="bg-gradient-to-r from-green-800 to-green-700 text-white">
<th className="p-3 text-left w-16">
No
</th>
@ -178,7 +277,7 @@ const PelaporanALForm = ({ onSubmit }: PelaporanALFormProps) => {
</thead>
<tbody>
{/* Section 1 */}
<tr className="bg-teal-50">
<tr className="bg-green-50">
<td className="p-3">I</td>
<td
className="p-3 font-medium"
@ -189,47 +288,74 @@ const PelaporanALForm = ({ onSubmit }: PelaporanALFormProps) => {
(%)
</td>
<td className="p-3"></td>
<td className="p-3">100</td>
<td className="p-3">
<span className="font-semibold text-green-700">
100
</span>
</td>
<td className="p-3"></td>
<td className="p-3"></td>
<td className="p-3"></td>
</tr>
{/* Technical Requirements */}
{/* Technical Requirements Section Header */}
<tr className="bg-gray-100">
<td className="p-3"></td>
<td
className="p-3 font-semibold text-gray-700"
colSpan={6}
>
1. Persyaratan Teknis
</td>
</tr>
{/* Technical Requirements A1-A5 */}
{[
"Instalasi pengolah air limbah",
"Flowmeter",
"Titik pengambilan sampel",
"Saluran air limbah & air hujan terpisah",
"Izin pembuangan air limbah",
// "Izin pembuangan air limbah",
].map((item, index) => (
<tr
key={index}
className="border-t"
className="border-t hover:bg-gray-50"
>
<td className="p-3">
<td className="p-3 font-medium">
A{index + 1}
</td>
<td className="p-3">
<div className="flex justify-between items-center w-full">
<div>{item}</div>
<div className="text-gray-800">
{item}
</div>
<Tooltip>
<TooltipTrigger>
<CircleHelp className="text-teal-600 w-5 h-5" />
<CircleHelp className="text-green-600 w-5 h-5" />
</TooltipTrigger>
<TooltipContent>
<p>
<TooltipContent className="bg-white p-3 rounded-lg shadow-lg border max-w-sm">
<h4 className="font-medium text-green-700 mb-1">
{item}
</h4>
<p className="text-sm text-gray-600">
Deskripsi
untuk {item}
persyaratan
teknis untuk{" "}
{item.toLowerCase()}
. Pastikan
data yang
diisi sesuai
dengan
kondisi
aktual.
</p>
</TooltipContent>
</Tooltip>
</div>
</td>
<td className="p-3">
{" "}
<Select>
<SelectTrigger className="w-24">
<SelectTrigger className="w-28 border-gray-300">
<SelectValue placeholder="Ada" />
</SelectTrigger>
<SelectContent>
@ -242,52 +368,95 @@ const PelaporanALForm = ({ onSubmit }: PelaporanALFormProps) => {
</SelectContent>
</Select>
</td>
<td className="p-3">100</td>
<td className="p-3"></td>
<td className="p-3"></td>
<td className="p-3"></td>
<td className="p-3 font-medium">
100
</td>
<td className="p-3">
<Button
variant="ghost"
size="sm"
className="flex items-center gap-1 text-green-700 hover:bg-green-50 hover:text-green-800"
onClick={() =>
openAttachmentUpload(
`A${index + 1}`
)
}
>
<Upload className="h-4 w-4" />
<span>Unggah</span>
</Button>
</td>
<td className="p-3">
<Badge
variant="outline"
className="bg-amber-50 text-amber-700 border-amber-200"
>
<Clock className="h-3 w-3 mr-1" />
Menunggu
</Badge>
</td>
</tr>
))}
{/* Implementation Section */}
{/* Implementation Section Header */}
<tr className="bg-gray-100">
<td className="p-3"></td>
<td
className="p-3 font-semibold text-gray-700"
colSpan={6}
>
2. Perijinan
</td>
</tr>
{/* Implementation Section A6-A10 */}
{[
{
name: "Pengujian air limbah",
hasAttachment: true,
},
{
name: "Pemenuhan baku mutu air limbah",
code: "A5",
name: "Izin pembuangan air limbah",
hasAttachment: false,
},
{
name: "Pelaksanaan dan pemutusan wewenang",
hasSelect: true,
},
{
name: "Pembuatan neraca air",
hasSelect: true,
},
{
name: "Sertifikasi kompetensi",
hasSelect: true,
},
].map((item, index) => (
].map((item) => (
<tr
key={index}
className="border-t"
key={item.code}
className="border-t hover:bg-gray-50"
>
<td className="p-3">
A{index + 6}
<td className="p-3 font-medium">
{item.code}
</td>
<td className="p-3">
<div className="flex justify-between items-center w-full">
<div>{item.name}</div>
<CircleHelp className="text-teal-600 w-5 h-5" />
<div className="text-gray-800">
{item.name}
</div>
<Tooltip>
<TooltipTrigger>
<CircleHelp className="text-green-600 w-5 h-5" />
</TooltipTrigger>
<TooltipContent className="bg-white p-3 rounded-lg shadow-lg border max-w-sm">
<h4 className="font-medium text-green-700 mb-1">
Info:{" "}
{item.name}
</h4>
<p className="text-sm text-gray-600">
Deskripsi
untuk
persyaratan{" "}
{item.name.toLowerCase()}
. Pastikan
data yang
diisi sesuai
dengan
dokumen
pendukung.
</p>
</TooltipContent>
</Tooltip>
</div>
</td>
<td className="p-3">
<Select>
<SelectTrigger className="w-24">
<SelectTrigger className="w-28 border-gray-300">
<SelectValue placeholder="Ada" />
</SelectTrigger>
<SelectContent>
@ -300,16 +469,206 @@ const PelaporanALForm = ({ onSubmit }: PelaporanALFormProps) => {
</SelectContent>
</Select>
</td>
<td className="p-3">100</td>
<td className="p-3 font-medium">
100
</td>
<td className="p-3">
{item.hasAttachment && (
<span className="text-teal-600">
Data...
{attachments[
item.code as keyof typeof attachments
] ? (
<Button
variant="ghost"
size="sm"
className="flex items-center gap-1 text-green-700 bg-green-50 hover:bg-green-100"
>
<CheckCircle2 className="h-4 w-4" />
<span className="truncate max-w-24">
{
attachments[
item.code as keyof typeof attachments
]?.name
}
</span>
</Button>
) : (
<Button
variant="ghost"
size="sm"
className="flex items-center gap-1 text-green-700 hover:bg-green-50 hover:text-green-800"
onClick={() =>
openAttachmentUpload(
item.code
)
}
>
<Upload className="h-4 w-4" />
<span>Data...</span>
</Button>
)}
</td>
<td className="p-3">
{item.code === "A6" ? (
<Badge className="bg-green-100 text-green-700 border-none">
<CheckCircle2 className="h-3 w-3 mr-1" />
Terverifikasi
</Badge>
) : (
<Badge
variant="outline"
className="bg-amber-50 text-amber-700 border-amber-200"
>
<Clock className="h-3 w-3 mr-1" />
Menunggu
</Badge>
)}
</td>
</tr>
))}
{/* Implementation Section Header */}
<tr className="bg-gray-100">
<td className="p-3"></td>
<td className="p-3"></td>
<td
className="p-3 font-semibold text-gray-700"
colSpan={6}
>
3. Pelaksanaan
</td>
</tr>
{/* Implementation Section A6-A10 */}
{[
{
code: "A6",
name: "Pengujian air limbah",
hasAttachment: true,
},
{
code: "A7",
name: "Pemenuhan baku mutu air limbah",
hasAttachment: true,
},
{
code: "A8",
name: "Pelaksanaan dan pemutusan wewenang",
hasAttachment: true,
},
{
code: "A9",
name: "Pembuatan neraca air",
hasAttachment: true,
},
{
code: "A10",
name: "Sertifikasi kompetensi",
hasAttachment: true,
},
].map((item) => (
<tr
key={item.code}
className="border-t hover:bg-gray-50"
>
<td className="p-3 font-medium">
{item.code}
</td>
<td className="p-3">
<div className="flex justify-between items-center w-full">
<div className="text-gray-800">
{item.name}
</div>
<Tooltip>
<TooltipTrigger>
<CircleHelp className="text-green-600 w-5 h-5" />
</TooltipTrigger>
<TooltipContent className="bg-white p-3 rounded-lg shadow-lg border max-w-sm">
<h4 className="font-medium text-green-700 mb-1">
Info:{" "}
{item.name}
</h4>
<p className="text-sm text-gray-600">
Deskripsi
untuk
persyaratan{" "}
{item.name.toLowerCase()}
. Pastikan
data yang
diisi sesuai
dengan
dokumen
pendukung.
</p>
</TooltipContent>
</Tooltip>
</div>
</td>
<td className="p-3">
<Select>
<SelectTrigger className="w-28 border-gray-300">
<SelectValue placeholder="Ada" />
</SelectTrigger>
<SelectContent>
<SelectItem value="ada">
Ada
</SelectItem>
<SelectItem value="tidak">
Tidak Ada
</SelectItem>
</SelectContent>
</Select>
</td>
<td className="p-3 font-medium">
100
</td>
<td className="p-3">
{attachments[
item.code as keyof typeof attachments
] ? (
<Button
variant="ghost"
size="sm"
className="flex items-center gap-1 text-green-700 bg-green-50 hover:bg-green-100"
>
<CheckCircle2 className="h-4 w-4" />
<span className="truncate max-w-24">
{
attachments[
item.code as keyof typeof attachments
]?.name
}
</span>
</Button>
) : (
<Button
variant="ghost"
size="sm"
className="flex items-center gap-1 text-green-700 hover:bg-green-50 hover:text-green-800"
onClick={() =>
openAttachmentUpload(
item.code
)
}
>
<Upload className="h-4 w-4" />
<span>Data...</span>
</Button>
)}
</td>
<td className="p-3">
{item.code === "A6" ? (
<Badge className="bg-green-100 text-green-700 border-none">
<CheckCircle2 className="h-3 w-3 mr-1" />
Terverifikasi
</Badge>
) : (
<Badge
variant="outline"
className="bg-amber-50 text-amber-700 border-amber-200"
>
<Clock className="h-3 w-3 mr-1" />
Menunggu
</Badge>
)}
</td>
</tr>
))}
</tbody>
@ -317,41 +676,57 @@ const PelaporanALForm = ({ onSubmit }: PelaporanALFormProps) => {
</div>
{/* Notes Section */}
<div className="bg-gray-50 p-6 rounded-lg border border-gray-200 mt-6">
<h2 className="text-lg font-semibold mb-3 text-gray-800">
Catatan
<Card className="border shadow-sm">
<CardContent className="p-5">
<h2 className="text-lg font-semibold mb-3 text-gray-800 flex items-center gap-2">
<span>Catatan</span>
{/* <span className="text-sm font-normal text-gray-500">
(Opsional)
</span> */}
</h2>
<Textarea
placeholder="Tambahkan catatan atau komentar tambahan di sini..."
className="min-h-[100px] bg-white"
className="min-h-[100px] bg-white border-gray-300 focus:border-green-500 focus:ring-green-500"
/>
</div>
</CardContent>
</Card>
{/* Agreement & Submit Section */}
<div className="mt-8 space-y-6">
<div className="flex items-start gap-3 p-4 bg-green-50 rounded-lg border border-teal-200">
<Checkbox id="agreement" className="mt-1" />
<div className="flex items-start gap-3 p-4 bg-green-50 rounded-lg border border-green-200">
<Checkbox
id="agreement"
className="mt-1 text-green-600 focus:ring-green-500"
/>
<div>
<Label
htmlFor="agreement"
className="text-sm leading-relaxed text-gray-700"
className="text-sm font-medium text-gray-800"
>
Dengan mencentang ini, 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.
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"
className="hover:bg-gray-100 gap-2"
>
<Save className="h-4 w-4" />
Simpan Draft
</Button>
<Button className="bg-[#166534] hover:bg-green-700 transition-colors px-8">
<Button className="bg-green-800 hover:bg-green-700 transition-colors px-8 gap-2">
<ArrowUpRight className="h-4 w-4" />
Kirim Laporan
</Button>
</div>