feat: Menambahkan validasi file dan relasi model
parent
6fabbe8708
commit
cae368adc0
|
@ -40,7 +40,7 @@ class PerusahaanRequest extends FormRequest
|
||||||
'JenisDokILId' => ['integer'],
|
'JenisDokILId' => ['integer'],
|
||||||
'VerifikatorId' => ['required', 'integer'],
|
'VerifikatorId' => ['required', 'integer'],
|
||||||
'IsPublish' => ['required', 'boolean'],
|
'IsPublish' => ['required', 'boolean'],
|
||||||
'ILDokumen' => ['string'],
|
'ILDokumen' => 'nullable|file|mimes:pdf|max:2048',
|
||||||
'Kawasan' => ['string'],
|
'Kawasan' => ['string'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace App\Models;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class Perusahaan extends Model
|
class Perusahaan extends Model
|
||||||
|
@ -92,7 +93,15 @@ class Perusahaan extends Model
|
||||||
return $this->belongsTo(JenisDokIL::class, 'JenisDokILId', 'JenisDokILId');
|
return $this->belongsTo(JenisDokIL::class, 'JenisDokILId', 'JenisDokILId');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function historyKegiatan()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(HistoryKegiatan::class, 'HistoryKegiatanId', 'HistoryKegiatanId');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function historyPerusahaan(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(HistoryPerusahaan::class, 'PerusahaanId', 'PerusahaanId');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,808 @@
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import AuthenticatedLayout from "@/layouts/authenticated-layout";
|
||||||
|
import { Head, Link, router, useForm } from "@inertiajs/react";
|
||||||
|
import Select from "react-select";
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from "@/components/ui/table";
|
||||||
|
|
||||||
|
// Komponen shadcn/ui untuk date range (contoh)
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/components/ui/popover";
|
||||||
|
import { Calendar } from "@/components/ui/calendar";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { ArrowLeft, CalendarIcon, Edit, Printer } from "lucide-react";
|
||||||
|
import { format } from "date-fns";
|
||||||
|
import { cn } from "@/lib/utils"; // biasanya helper classNames
|
||||||
|
import { DateRange } from "react-day-picker";
|
||||||
|
import { FileText } from "lucide-react";
|
||||||
|
import {
|
||||||
|
Perusahaan,
|
||||||
|
HistoryKegiatan,
|
||||||
|
HistoryPerusahaan as HistoryPerusahaanType,
|
||||||
|
} from "@/types/perusahaan";
|
||||||
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
|
import { useToast } from "@/hooks/use-toast";
|
||||||
|
|
||||||
|
type DetailHistoryPerusahaanProps = {
|
||||||
|
perusahaan: Perusahaan;
|
||||||
|
historyKegiatan: HistoryKegiatan[];
|
||||||
|
historyPerusahaan: HistoryPerusahaanType[]; // data existing
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function DetailHistoryPerusahaan({
|
||||||
|
perusahaan,
|
||||||
|
historyKegiatan,
|
||||||
|
historyPerusahaan = [],
|
||||||
|
}: DetailHistoryPerusahaanProps) {
|
||||||
|
const { toast } = useToast();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("Isi Data History Perusahaan:", historyPerusahaan);
|
||||||
|
}, [historyPerusahaan]);
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
// 1. STATE FILTER
|
||||||
|
// --------------------
|
||||||
|
// Date range
|
||||||
|
const [dateRange, setDateRange] = useState<DateRange | undefined>({
|
||||||
|
from: undefined,
|
||||||
|
to: undefined,
|
||||||
|
});
|
||||||
|
// Kelompok Kegiatan
|
||||||
|
const [selectedKegiatan, setSelectedKegiatan] = useState<{
|
||||||
|
value: string;
|
||||||
|
label: string;
|
||||||
|
} | null>(null);
|
||||||
|
|
||||||
|
// State data terfilter
|
||||||
|
const [filteredData, setFilteredData] =
|
||||||
|
useState<HistoryPerusahaanType[]>(historyPerusahaan);
|
||||||
|
|
||||||
|
// Fungsi untuk memproses filter
|
||||||
|
function handleFilter() {
|
||||||
|
let filtered = [...historyPerusahaan];
|
||||||
|
|
||||||
|
// Filter rentang tanggal
|
||||||
|
if (dateRange?.from && dateRange?.to) {
|
||||||
|
const fromDay = format(dateRange.from, "yyyy-MM-dd");
|
||||||
|
const toDay = format(dateRange.to, "yyyy-MM-dd");
|
||||||
|
|
||||||
|
filtered = filtered.filter((item) => {
|
||||||
|
if (!item.TanggalHistory) return false;
|
||||||
|
const itemDay = format(
|
||||||
|
new Date(item.TanggalHistory),
|
||||||
|
"yyyy-MM-dd"
|
||||||
|
);
|
||||||
|
return itemDay >= fromDay && itemDay <= toDay;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter Kelompok Kegiatan
|
||||||
|
if (selectedKegiatan) {
|
||||||
|
filtered = filtered.filter(
|
||||||
|
(item) =>
|
||||||
|
item.HistoryKegiatanId.toString() === selectedKegiatan.value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
setFilteredData(filtered);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fungsi untuk mereset filter pencarian
|
||||||
|
function handleReset() {
|
||||||
|
setDateRange({ from: undefined, to: undefined });
|
||||||
|
setSelectedKegiatan(null);
|
||||||
|
setFilteredData(historyPerusahaan);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleBack() {
|
||||||
|
// Misal kembali ke halaman sebelumnya
|
||||||
|
window.history.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlePrint() {
|
||||||
|
// Contoh simpel: memanggil window.print()
|
||||||
|
window.print();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleExportPDF() {
|
||||||
|
// Contoh panggil route export PDF, atau link ke PDF
|
||||||
|
// Misal router.visit(route("pdf.export", { id: 123 }));
|
||||||
|
// Atau window.open("/path/to/pdf", "_blank");
|
||||||
|
alert("Export PDF belum diimplementasikan.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
// 2. STATE FORM TAMBAH HISTORY
|
||||||
|
// --------------------
|
||||||
|
const [showModal, setShowModal] = useState(false);
|
||||||
|
|
||||||
|
const { data, setData, post, processing, errors, reset } = useForm({
|
||||||
|
PerusahaanId: perusahaan.PerusahaanId,
|
||||||
|
NomorHistory: "",
|
||||||
|
TanggalHistory: "",
|
||||||
|
HistoryKegiatanId: "",
|
||||||
|
KeteranganHistory: "",
|
||||||
|
DokumenHistory: null as File | null,
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleSubmit(e: React.FormEvent) {
|
||||||
|
e.preventDefault();
|
||||||
|
post(route("admin.history_perusahaan.store", perusahaan.PerusahaanId), {
|
||||||
|
onSuccess: () => {
|
||||||
|
router.visit(window.location.href, { replace: true });
|
||||||
|
setShowModal(false);
|
||||||
|
reset();
|
||||||
|
toast({
|
||||||
|
title: "Sukses",
|
||||||
|
description: "History Perusahaan berhasil ditambahkan",
|
||||||
|
variant: "default",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: (errors) => {
|
||||||
|
toast({
|
||||||
|
title: "Error",
|
||||||
|
description: "Gagal menambahkan history perusahaan",
|
||||||
|
variant: "destructive",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
// 3. STATE & FORM UNTUK EDIT HISTORY
|
||||||
|
// --------------------
|
||||||
|
const [showEditModal, setShowEditModal] = useState(false);
|
||||||
|
const [editingItem, setEditingItem] =
|
||||||
|
useState<HistoryPerusahaanType | null>(null);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: editData,
|
||||||
|
setData: setEditData,
|
||||||
|
post: postEdit,
|
||||||
|
processing: editProcessing,
|
||||||
|
errors: editErrors,
|
||||||
|
reset: resetEditForm,
|
||||||
|
} = useForm({
|
||||||
|
HistoryPerusahaanId: "",
|
||||||
|
PerusahaanId: perusahaan.PerusahaanId,
|
||||||
|
NomorHistory: "",
|
||||||
|
TanggalHistory: "",
|
||||||
|
HistoryKegiatanId: "",
|
||||||
|
KeteranganHistory: "",
|
||||||
|
DokumenHistory: null as File | null,
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleEdit(item: HistoryPerusahaanType) {
|
||||||
|
setEditingItem(item);
|
||||||
|
setEditData("HistoryPerusahaanId", item.HistoryPerusahaanId);
|
||||||
|
setEditData("NomorHistory", item.NomorHistory);
|
||||||
|
setEditData("TanggalHistory", item.TanggalHistory);
|
||||||
|
setEditData("HistoryKegiatanId", item.HistoryKegiatanId.toString());
|
||||||
|
setEditData("KeteranganHistory", item.KeteranganHistory);
|
||||||
|
setShowEditModal(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleEditSubmit(e: React.FormEvent) {
|
||||||
|
e.preventDefault();
|
||||||
|
postEdit(
|
||||||
|
route(
|
||||||
|
"admin.history_perusahaan.update",
|
||||||
|
editData.HistoryPerusahaanId
|
||||||
|
),
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
router.visit(window.location.href, { replace: true });
|
||||||
|
setShowEditModal(false);
|
||||||
|
resetEditForm();
|
||||||
|
toast({
|
||||||
|
title: "Sukses",
|
||||||
|
description: "History Perusahaan berhasil diperbarui",
|
||||||
|
variant: "default",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: () => {
|
||||||
|
toast({
|
||||||
|
title: "Error",
|
||||||
|
description: "Gagal memperbarui history perusahaan",
|
||||||
|
variant: "destructive",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
// 4. RENDER HALAMAN
|
||||||
|
// --------------------
|
||||||
|
return (
|
||||||
|
<AuthenticatedLayout header="Detail History Perusahaan">
|
||||||
|
<Head title="Detail History Perusahaan" />
|
||||||
|
<div className="container mx-auto p-4">
|
||||||
|
<div className="flex items-center justify-between mb-4">
|
||||||
|
<div>
|
||||||
|
<h2 className="text-lg font-semibold mb-2 text-gray-800">
|
||||||
|
History Perusahaan: {perusahaan.NamaPerusahaan}
|
||||||
|
</h2>
|
||||||
|
<p className="text-sm text-gray-600">
|
||||||
|
Nomor Induk: {perusahaan.NomorInduk || "-"}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<button
|
||||||
|
onClick={handleBack}
|
||||||
|
className="bg-blue-500 text-white px-2 py-1 rounded-md flex items-center gap-1 hover:bg-blue-600"
|
||||||
|
>
|
||||||
|
<ArrowLeft className="w-4 h-4" />
|
||||||
|
BACK
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handlePrint}
|
||||||
|
className="bg-blue-500 text-white px-2 py-1 rounded-md flex items-center gap-1 hover:bg-blue-600"
|
||||||
|
>
|
||||||
|
<Printer className="w-4 h-4" />
|
||||||
|
Print
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleExportPDF}
|
||||||
|
className="bg-blue-500 text-white px-2 py-1 rounded-md flex items-center gap-1 hover:bg-blue-600"
|
||||||
|
>
|
||||||
|
<FileText className="w-4 h-4" />
|
||||||
|
Export PDF
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Bagian Filter */}
|
||||||
|
<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">
|
||||||
|
Pencarian
|
||||||
|
</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
|
{/* Filter Rentang Tanggal */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label className="text-sm font-medium">
|
||||||
|
Rentang Tanggal
|
||||||
|
</label>
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
className={cn(
|
||||||
|
"w-full justify-start text-left font-normal",
|
||||||
|
!dateRange?.from &&
|
||||||
|
"text-muted-foreground"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<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 Tanggal"}
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent
|
||||||
|
className="w-auto p-0"
|
||||||
|
align="start"
|
||||||
|
>
|
||||||
|
<Calendar
|
||||||
|
initialFocus
|
||||||
|
mode="range"
|
||||||
|
defaultMonth={dateRange?.from}
|
||||||
|
selected={dateRange}
|
||||||
|
onSelect={setDateRange}
|
||||||
|
numberOfMonths={2}
|
||||||
|
/>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Filter Kelompok Kegiatan - Using react-select */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label className="text-sm font-medium">
|
||||||
|
Kelompok Kegiatan
|
||||||
|
</label>
|
||||||
|
<Select
|
||||||
|
className="basic-single"
|
||||||
|
classNamePrefix="select"
|
||||||
|
value={selectedKegiatan}
|
||||||
|
onChange={(option) =>
|
||||||
|
setSelectedKegiatan(option)
|
||||||
|
}
|
||||||
|
options={historyKegiatan.map((hk) => ({
|
||||||
|
value: hk.HistoryKegiatanId.toString(),
|
||||||
|
label: hk.NamaHistoryKegiatan,
|
||||||
|
}))}
|
||||||
|
isClearable
|
||||||
|
placeholder="-- Pilih --"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Tombol Cari */}
|
||||||
|
<div className="mt-4 flex gap-2">
|
||||||
|
<Button
|
||||||
|
onClick={handleFilter}
|
||||||
|
className="bg-green-600 hover:bg-green-700 text-white"
|
||||||
|
>
|
||||||
|
Cari
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={handleReset}
|
||||||
|
className="bg-gray-600 hover:bg-gray-700 text-white"
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Tombol Tambah History Perusahaan */}
|
||||||
|
<div className="mb-6">
|
||||||
|
<button
|
||||||
|
onClick={() => setShowModal(true)}
|
||||||
|
className="px-4 py-2 bg-green-600 text-white rounded-md"
|
||||||
|
>
|
||||||
|
Tambah History Perusahaan
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Tabel Data History Perusahaan (menggunakan filteredData) */}
|
||||||
|
<div className="w-full overflow-x-auto">
|
||||||
|
<Table className="min-w-[1000px] border-collapse">
|
||||||
|
<TableHeader>
|
||||||
|
<TableRow className="border-b border-t bg-green-800">
|
||||||
|
<TableHead className="w-[50px] border-r border-l text-center text-white">
|
||||||
|
No.
|
||||||
|
</TableHead>
|
||||||
|
<TableHead className="border-r text-center text-white">
|
||||||
|
Nomor Surat
|
||||||
|
</TableHead>
|
||||||
|
<TableHead className="border-r text-center text-white">
|
||||||
|
Tanggal Surat
|
||||||
|
</TableHead>
|
||||||
|
<TableHead className="border-r text-center text-white">
|
||||||
|
Kelompok Kegiatan
|
||||||
|
</TableHead>
|
||||||
|
<TableHead className="border-r text-center text-white">
|
||||||
|
Keterangan
|
||||||
|
</TableHead>
|
||||||
|
<TableHead className="border-r text-center text-white">
|
||||||
|
Dokumen
|
||||||
|
</TableHead>
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody className="border-b">
|
||||||
|
{filteredData.length > 0 ? (
|
||||||
|
filteredData.map((item, index) => (
|
||||||
|
<TableRow
|
||||||
|
key={item.HistoryPerusahaanId}
|
||||||
|
className="border-b"
|
||||||
|
>
|
||||||
|
<TableCell className="font-medium text-center border-r border-l">
|
||||||
|
{index + 1}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="text-center border-r">
|
||||||
|
{item.NomorHistory || "-"}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="text-center border-r">
|
||||||
|
{item.TanggalHistory || "-"}
|
||||||
|
|
||||||
|
{/* {item.TanggalHistory
|
||||||
|
? new Date(
|
||||||
|
item.TanggalHistory
|
||||||
|
).toLocaleDateString(
|
||||||
|
"id-ID",
|
||||||
|
{
|
||||||
|
day: "2-digit",
|
||||||
|
month: "long",
|
||||||
|
year: "numeric",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
: "-"} */}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="text-center border-r">
|
||||||
|
{/* Anda bisa menampilkan data dari relasi, misal item.kegiatan?.NamaHistoryKegiatan */}
|
||||||
|
<div className="flex items-center justify-center">
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
handleEdit(item)
|
||||||
|
}
|
||||||
|
className="px-2 py-1 bg-blue-100 font-normal hover:underline flex items-center gap-1 rounded-md"
|
||||||
|
>
|
||||||
|
<Edit className="h-3 w-3 text-blue-500" />
|
||||||
|
{item.history_kegiatan
|
||||||
|
?.NamaHistoryKegiatan ||
|
||||||
|
"-"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="text-center border-r">
|
||||||
|
{item.KeteranganHistory || "-"}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="text-center border-r">
|
||||||
|
<div className="flex items-center justify-center">
|
||||||
|
{item.DokumenHistory && (
|
||||||
|
<a
|
||||||
|
href={`/storage/${item.DokumenHistory}`}
|
||||||
|
target="_blank"
|
||||||
|
className="px-2 py-1 bg-blue-100 font-normal hover:underline flex items-center gap-1 rounded-md"
|
||||||
|
>
|
||||||
|
<FileText className="h-3 w-3 text-blue-500" />
|
||||||
|
Lihat Dokumen
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell
|
||||||
|
colSpan={6}
|
||||||
|
className="h-24 text-center"
|
||||||
|
>
|
||||||
|
Tidak ada data
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Modal Tambah History Perusahaan */}
|
||||||
|
{showModal && (
|
||||||
|
<div className="fixed inset-0 flex items-center justify-center z-50 bg-black/50">
|
||||||
|
<div className="bg-white p-6 rounded-md w-full max-w-md">
|
||||||
|
<h2 className="text-xl font-semibold mb-4">
|
||||||
|
Tambah History Perusahaan
|
||||||
|
</h2>
|
||||||
|
<form
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
encType="multipart/form-data"
|
||||||
|
>
|
||||||
|
{/* Nomor Surat */}
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block font-medium mb-1">
|
||||||
|
Nomor Surat*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={data.NomorHistory}
|
||||||
|
onChange={(e) =>
|
||||||
|
setData("NomorHistory", e.target.value)
|
||||||
|
}
|
||||||
|
className="border border-gray-300 rounded w-full p-2"
|
||||||
|
/>
|
||||||
|
{errors.NomorHistory && (
|
||||||
|
<div className="text-red-500 text-sm">
|
||||||
|
{errors.NomorHistory}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Tanggal Surat */}
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block font-medium mb-1">
|
||||||
|
Tanggal Surat*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
value={data.TanggalHistory}
|
||||||
|
onChange={(e) =>
|
||||||
|
setData(
|
||||||
|
"TanggalHistory",
|
||||||
|
e.target.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className="border border-gray-300 rounded w-full p-2"
|
||||||
|
/>
|
||||||
|
{errors.TanggalHistory && (
|
||||||
|
<div className="text-red-500 text-sm">
|
||||||
|
{errors.TanggalHistory}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Kelompok Kegiatan */}
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block font-medium mb-1">
|
||||||
|
Kelompok Kegiatan*
|
||||||
|
</label>
|
||||||
|
<Select
|
||||||
|
options={historyKegiatan.map((hk) => ({
|
||||||
|
value: hk.HistoryKegiatanId.toString(),
|
||||||
|
label: hk.NamaHistoryKegiatan,
|
||||||
|
}))}
|
||||||
|
onChange={(selected) =>
|
||||||
|
setData(
|
||||||
|
"HistoryKegiatanId",
|
||||||
|
selected?.value?.toString() || ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
placeholder="-- Pilih --"
|
||||||
|
className="text-sm"
|
||||||
|
/>
|
||||||
|
{errors.HistoryKegiatanId && (
|
||||||
|
<div className="text-red-500 text-sm">
|
||||||
|
{errors.HistoryKegiatanId}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Keterangan */}
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block font-medium mb-1">
|
||||||
|
Keterangan
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
value={data.KeteranganHistory}
|
||||||
|
onChange={(e) =>
|
||||||
|
setData(
|
||||||
|
"KeteranganHistory",
|
||||||
|
e.target.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className="border border-gray-300 rounded w-full p-2"
|
||||||
|
/>
|
||||||
|
{errors.KeteranganHistory && (
|
||||||
|
<div className="text-red-500 text-sm">
|
||||||
|
{errors.KeteranganHistory}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Upload Dokumen */}
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block font-medium mb-1">
|
||||||
|
Upload Dokumen*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
onChange={(e) =>
|
||||||
|
setData(
|
||||||
|
"DokumenHistory",
|
||||||
|
e.target.files
|
||||||
|
? e.target.files[0]
|
||||||
|
: null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className="border border-gray-300 rounded w-full p-2"
|
||||||
|
/>
|
||||||
|
{errors.DokumenHistory && (
|
||||||
|
<div className="text-red-500 text-sm">
|
||||||
|
{errors.DokumenHistory}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Tombol Aksi */}
|
||||||
|
<div className="flex justify-end mt-6">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => {
|
||||||
|
setShowModal(false);
|
||||||
|
reset();
|
||||||
|
}}
|
||||||
|
className="px-4 py-2 bg-gray-300 rounded-md mr-2"
|
||||||
|
>
|
||||||
|
Batal
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={processing}
|
||||||
|
className="px-4 py-2 bg-blue-600 text-white rounded-md"
|
||||||
|
>
|
||||||
|
Simpan
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Modal Edit History Perusahaan */}
|
||||||
|
{showEditModal && (
|
||||||
|
<div className="fixed inset-0 flex items-center justify-center z-50 bg-black/50">
|
||||||
|
<div className="bg-white p-6 rounded-md w-full max-w-md">
|
||||||
|
<h2 className="text-xl font-semibold mb-4">
|
||||||
|
Edit History Perusahaan
|
||||||
|
</h2>
|
||||||
|
<form
|
||||||
|
onSubmit={handleEditSubmit}
|
||||||
|
encType="multipart/form-data"
|
||||||
|
>
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block font-medium mb-1">
|
||||||
|
Nomor Surat*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={editData.NomorHistory}
|
||||||
|
onChange={(e) =>
|
||||||
|
setEditData(
|
||||||
|
"NomorHistory",
|
||||||
|
e.target.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className="border border-gray-300 rounded w-full p-2"
|
||||||
|
/>
|
||||||
|
{editErrors.NomorHistory && (
|
||||||
|
<div className="text-red-500 text-sm">
|
||||||
|
{editErrors.NomorHistory}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block font-medium mb-1">
|
||||||
|
Tanggal Surat*
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
value={editData.TanggalHistory}
|
||||||
|
onChange={(e) =>
|
||||||
|
setEditData(
|
||||||
|
"TanggalHistory",
|
||||||
|
e.target.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className="border border-gray-300 rounded w-full p-2"
|
||||||
|
/>
|
||||||
|
{editErrors.TanggalHistory && (
|
||||||
|
<div className="text-red-500 text-sm">
|
||||||
|
{editErrors.TanggalHistory}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block font-medium mb-1">
|
||||||
|
Kelompok Kegiatan*
|
||||||
|
</label>
|
||||||
|
<Select
|
||||||
|
options={historyKegiatan.map((hk) => ({
|
||||||
|
value: hk.HistoryKegiatanId.toString(),
|
||||||
|
label: hk.NamaHistoryKegiatan,
|
||||||
|
}))}
|
||||||
|
value={
|
||||||
|
historyKegiatan.find(
|
||||||
|
(hk) =>
|
||||||
|
hk.HistoryKegiatanId.toString() ===
|
||||||
|
editData.HistoryKegiatanId
|
||||||
|
)
|
||||||
|
? {
|
||||||
|
value: editData.HistoryKegiatanId,
|
||||||
|
label:
|
||||||
|
historyKegiatan.find(
|
||||||
|
(hk) =>
|
||||||
|
hk.HistoryKegiatanId.toString() ===
|
||||||
|
editData.HistoryKegiatanId
|
||||||
|
)?.NamaHistoryKegiatan ||
|
||||||
|
"",
|
||||||
|
}
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
onChange={(selected) =>
|
||||||
|
setEditData(
|
||||||
|
"HistoryKegiatanId",
|
||||||
|
selected?.value?.toString() || ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
placeholder="-- Pilih --"
|
||||||
|
className="text-sm"
|
||||||
|
/>
|
||||||
|
{editErrors.HistoryKegiatanId && (
|
||||||
|
<div className="text-red-500 text-sm">
|
||||||
|
{editErrors.HistoryKegiatanId}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block font-medium mb-1">
|
||||||
|
Keterangan
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
value={editData.KeteranganHistory}
|
||||||
|
onChange={(e) =>
|
||||||
|
setEditData(
|
||||||
|
"KeteranganHistory",
|
||||||
|
e.target.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className="border border-gray-300 rounded w-full p-2"
|
||||||
|
/>
|
||||||
|
{editErrors.KeteranganHistory && (
|
||||||
|
<div className="text-red-500 text-sm">
|
||||||
|
{editErrors.KeteranganHistory}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block font-medium mb-1">
|
||||||
|
Upload Dokumen
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
onChange={(e) =>
|
||||||
|
setEditData(
|
||||||
|
"DokumenHistory",
|
||||||
|
e.target.files
|
||||||
|
? e.target.files[0]
|
||||||
|
: null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className="border border-gray-300 rounded w-full p-2"
|
||||||
|
/>
|
||||||
|
{editErrors.DokumenHistory && (
|
||||||
|
<div className="text-red-500 text-sm">
|
||||||
|
{editErrors.DokumenHistory}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{/* Tombol Lihat File saat ini */}
|
||||||
|
{editingItem?.DokumenHistory && (
|
||||||
|
<Button
|
||||||
|
className="bg-green-100 mt-2"
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={() =>
|
||||||
|
window.open(
|
||||||
|
`/storage/${editingItem.DokumenHistory}`,
|
||||||
|
"_blank"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Lihat File saat ini
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-end mt-6">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => {
|
||||||
|
setShowEditModal(false);
|
||||||
|
resetEditForm();
|
||||||
|
}}
|
||||||
|
className="px-4 py-2 bg-gray-300 rounded-md mr-2"
|
||||||
|
>
|
||||||
|
Batal
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={editProcessing}
|
||||||
|
className="px-4 py-2 bg-blue-600 text-white rounded-md"
|
||||||
|
>
|
||||||
|
Simpan
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</AuthenticatedLayout>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,301 @@
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import AuthenticatedLayout from "@/layouts/authenticated-layout";
|
||||||
|
import {
|
||||||
|
HistoryKegiatan,
|
||||||
|
JenisKegiatan,
|
||||||
|
Kabupaten,
|
||||||
|
Perusahaan,
|
||||||
|
} from "@/types/perusahaan";
|
||||||
|
import { Head } from "@inertiajs/react";
|
||||||
|
import { Search } from "lucide-react";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { HistoryPerusahaanTable } from "@/components/HistoryPerusahaan/TableHistory";
|
||||||
|
import Select from "react-select"; // Import React-Select
|
||||||
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
|
|
||||||
|
type HistoryPerusahaanIndexProps = {
|
||||||
|
perusahaan?: Perusahaan[];
|
||||||
|
historyKegiatan?: HistoryKegiatan[];
|
||||||
|
kabupaten?: Kabupaten[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function HistoryPerusahaanIndex({
|
||||||
|
perusahaan = [], // Default to empty array
|
||||||
|
historyKegiatan = [], // Default to empty array
|
||||||
|
kabupaten = [], // Default to empty array
|
||||||
|
}: HistoryPerusahaanIndexProps) {
|
||||||
|
// Define more precise types for select options
|
||||||
|
type SelectOption = {
|
||||||
|
value: string;
|
||||||
|
label: string;
|
||||||
|
kabupatenId?: string;
|
||||||
|
kabupatenName?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define options first before using them
|
||||||
|
const historyKegiatanOptions: SelectOption[] = historyKegiatan.map(
|
||||||
|
(jk) => ({
|
||||||
|
value: jk.HistoryKegiatanId.toString(),
|
||||||
|
label: jk.NamaHistoryKegiatan,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const kabupatenOptions: SelectOption[] = kabupaten.map((k) => ({
|
||||||
|
value: k.KabupatenId.toString(),
|
||||||
|
label: k.NamaKabupaten,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const companyOptions: SelectOption[] = perusahaan.map((c) => {
|
||||||
|
const kabupatenName =
|
||||||
|
c.kelurahan?.kecamatan?.kabupaten?.NamaKabupaten || "Unknown";
|
||||||
|
return {
|
||||||
|
value: c.PerusahaanId.toString(),
|
||||||
|
label: c.NamaPerusahaan,
|
||||||
|
kabupatenId:
|
||||||
|
c.kelurahan?.kecamatan?.kabupaten?.KabupatenId?.toString(),
|
||||||
|
kabupatenName: kabupatenName,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// State management with more explicit typing
|
||||||
|
const [selectedHistoryKegiatan, setSelectedHistoryKegiatan] =
|
||||||
|
useState<SelectOption | null>(null);
|
||||||
|
const [selectedKabupaten, setSelectedKabupaten] =
|
||||||
|
useState<SelectOption | null>(null);
|
||||||
|
const [company, setCompany] = useState<SelectOption | null>(
|
||||||
|
companyOptions.length > 0 ? companyOptions[0] : null
|
||||||
|
);
|
||||||
|
|
||||||
|
// Now initialize filteredCompanies after companyOptions is defined
|
||||||
|
const [filteredCompanies, setFilteredCompanies] = useState(companyOptions);
|
||||||
|
|
||||||
|
// Add state for number search
|
||||||
|
const [nomorPerusahaan, setNomorPerusahaan] = useState<string>("");
|
||||||
|
|
||||||
|
// Add state for filtered perusahaan data
|
||||||
|
const [filteredPerusahaan, setFilteredPerusahaan] =
|
||||||
|
useState<Perusahaan[]>(perusahaan);
|
||||||
|
|
||||||
|
// Update filtered companies when kabupaten selection changes
|
||||||
|
useEffect(() => {
|
||||||
|
if (selectedKabupaten) {
|
||||||
|
const filtered = companyOptions.filter(
|
||||||
|
(option) => option.kabupatenId === selectedKabupaten.value
|
||||||
|
);
|
||||||
|
setFilteredCompanies(filtered);
|
||||||
|
} else {
|
||||||
|
setFilteredCompanies(companyOptions);
|
||||||
|
}
|
||||||
|
}, [selectedKabupaten]);
|
||||||
|
|
||||||
|
// Explicit typing for onChange handlers
|
||||||
|
const handleCompanyChange = (selectedOption: SelectOption | null) => {
|
||||||
|
setCompany(selectedOption);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNomorPerusahaanChange = (
|
||||||
|
e: React.ChangeEvent<HTMLInputElement>
|
||||||
|
) => {
|
||||||
|
setNomorPerusahaan(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Search function
|
||||||
|
const handleSearch = () => {
|
||||||
|
// Start with all perusahaan data
|
||||||
|
let results = [...perusahaan];
|
||||||
|
|
||||||
|
// Filter by nomor perusahaan if provided
|
||||||
|
if (nomorPerusahaan.trim() !== "") {
|
||||||
|
results = results.filter((p) =>
|
||||||
|
p.NomorInduk?.toLowerCase().includes(
|
||||||
|
nomorPerusahaan.toLowerCase()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by selected company if provided
|
||||||
|
if (company) {
|
||||||
|
results = results.filter(
|
||||||
|
(p) => p.PerusahaanId.toString() === company.value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by selected kabupaten if provided
|
||||||
|
if (selectedKabupaten) {
|
||||||
|
results = results.filter((p) => {
|
||||||
|
// Handle potential null/undefined values safely
|
||||||
|
const kabupatenId =
|
||||||
|
p.kelurahan?.kecamatan?.kabupaten?.KabupatenId;
|
||||||
|
return kabupatenId
|
||||||
|
? kabupatenId.toString() === selectedKabupaten.value
|
||||||
|
: false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by selected history kegiatan if provided
|
||||||
|
if (selectedHistoryKegiatan) {
|
||||||
|
results = results.filter((p) => {
|
||||||
|
// Check if historyKegiatan exists and is an array
|
||||||
|
const historyKegiatanArray = p.historyKegiatan;
|
||||||
|
if (
|
||||||
|
!historyKegiatanArray ||
|
||||||
|
!Array.isArray(historyKegiatanArray)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if any historyKegiatan matches the selected one
|
||||||
|
return historyKegiatanArray.some((hk) => {
|
||||||
|
return (
|
||||||
|
hk &&
|
||||||
|
hk.HistoryKegiatanId &&
|
||||||
|
hk.HistoryKegiatanId.toString() ===
|
||||||
|
selectedHistoryKegiatan.value
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the filtered results
|
||||||
|
setFilteredPerusahaan(results);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Custom styles for React-Select
|
||||||
|
const selectStyles = {
|
||||||
|
control: (base: any) => ({
|
||||||
|
...base,
|
||||||
|
minHeight: "38px",
|
||||||
|
borderRadius: "0.375rem",
|
||||||
|
borderColor: "#e2e8f0",
|
||||||
|
boxShadow: "none",
|
||||||
|
"&:hover": {
|
||||||
|
borderColor: "#cbd5e0",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AuthenticatedLayout header={"History Perusahaan"}>
|
||||||
|
<Head title="History Perusahaan" />
|
||||||
|
<div className="container mx-auto p-4">
|
||||||
|
{/* Filter Section */}
|
||||||
|
<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
|
||||||
|
</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
|
{/* Left Column */}
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="grid grid-cols-3 items-center gap-4">
|
||||||
|
<label className="text-sm font-medium text-gray-700">
|
||||||
|
Nomor Perusahaan
|
||||||
|
</label>
|
||||||
|
<div className="col-span-2">
|
||||||
|
<Input
|
||||||
|
placeholder="Masukkan Nomor Perusahaan"
|
||||||
|
className="w-full"
|
||||||
|
value={nomorPerusahaan}
|
||||||
|
onChange={
|
||||||
|
handleNomorPerusahaanChange
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-3 items-center gap-4">
|
||||||
|
<label className="text-sm font-medium text-gray-700">
|
||||||
|
Perusahaan
|
||||||
|
</label>
|
||||||
|
<div className="col-span-2">
|
||||||
|
<Select
|
||||||
|
className="basic-single"
|
||||||
|
classNamePrefix="select"
|
||||||
|
value={company}
|
||||||
|
onChange={handleCompanyChange}
|
||||||
|
options={filteredCompanies}
|
||||||
|
isClearable={true}
|
||||||
|
isSearchable={true}
|
||||||
|
placeholder="Pilih Perusahaan"
|
||||||
|
noOptionsMessage={() =>
|
||||||
|
"Tidak ada data"
|
||||||
|
}
|
||||||
|
styles={selectStyles}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right Column */}
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="grid grid-cols-3 items-center gap-4">
|
||||||
|
<label className="text-sm font-medium text-gray-700">
|
||||||
|
Kabupaten/Kota
|
||||||
|
</label>
|
||||||
|
<div className="col-span-2">
|
||||||
|
<Select
|
||||||
|
className="basic-single"
|
||||||
|
classNamePrefix="select"
|
||||||
|
value={selectedKabupaten}
|
||||||
|
onChange={setSelectedKabupaten}
|
||||||
|
options={kabupatenOptions}
|
||||||
|
isClearable={true}
|
||||||
|
isSearchable={true}
|
||||||
|
placeholder="Pilih Kabupaten/Kota"
|
||||||
|
noOptionsMessage={() =>
|
||||||
|
"Tidak ada data"
|
||||||
|
}
|
||||||
|
styles={selectStyles}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-3 items-center gap-4">
|
||||||
|
<label className="text-sm font-medium text-gray-700">
|
||||||
|
Kelompok Kegiatan
|
||||||
|
</label>
|
||||||
|
<div className="col-span-2">
|
||||||
|
<Select
|
||||||
|
className="basic-single"
|
||||||
|
classNamePrefix="select"
|
||||||
|
value={selectedHistoryKegiatan}
|
||||||
|
onChange={
|
||||||
|
setSelectedHistoryKegiatan
|
||||||
|
}
|
||||||
|
options={historyKegiatanOptions}
|
||||||
|
isClearable={true}
|
||||||
|
isSearchable={true}
|
||||||
|
placeholder="Pilih Kelompok Kegiatan"
|
||||||
|
noOptionsMessage={() =>
|
||||||
|
"Tidak ada data"
|
||||||
|
}
|
||||||
|
styles={selectStyles}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex justify-end mt-6">
|
||||||
|
<Button
|
||||||
|
className="bg-green-600 hover:bg-green-700 text-white"
|
||||||
|
onClick={handleSearch}
|
||||||
|
>
|
||||||
|
<Search className="w-4 h-4 mr-2" />
|
||||||
|
Cari
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Table Section - Now uses filteredPerusahaan */}
|
||||||
|
<HistoryPerusahaanTable data={filteredPerusahaan} />
|
||||||
|
</div>
|
||||||
|
</AuthenticatedLayout>
|
||||||
|
);
|
||||||
|
}
|
|
@ -33,6 +33,44 @@ export interface Perusahaan {
|
||||||
JenisDokIL: {
|
JenisDokIL: {
|
||||||
NamaJenisDokIL: string;
|
NamaJenisDokIL: string;
|
||||||
};
|
};
|
||||||
|
Kabupaten?: string; // Make sure this field exists
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NamaPerusahaan {
|
||||||
|
PerusahaanId: number;
|
||||||
|
NamaPerusahaan: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HistoryKegiatan {
|
||||||
|
HistoryKegiatanId: number;
|
||||||
|
NamaHistoryKegiatan: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HistoryPerusahaan {
|
||||||
|
[x: string]: any;
|
||||||
|
PerusahaanId: number;
|
||||||
|
NamaPerusahaan: string;
|
||||||
|
HistoryKegiatanId: number;
|
||||||
|
NamaHistoryKegiatan: string;
|
||||||
|
TanggalHistory: string;
|
||||||
|
NomorHistory: string;
|
||||||
|
DokumenHistory: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PerizinanLingkunganType {
|
||||||
|
[x: string]: any;
|
||||||
|
PerusahaanId: number;
|
||||||
|
NomorInduk: string;
|
||||||
|
NamaPerusahaan: string;
|
||||||
|
JenisKegiatanId: number;
|
||||||
|
JenisDokilId: number;
|
||||||
|
Alamat: string;
|
||||||
|
Telepon: string;
|
||||||
|
Fax: string;
|
||||||
|
Email: string;
|
||||||
|
ILNomor: string;
|
||||||
|
ILTanggal: string;
|
||||||
|
ILDokumen: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HukumType {
|
export interface HukumType {
|
||||||
|
|
Loading…
Reference in New Issue