feat: Menambahkan komponen Tabel Detail dan Tabel History

main
marszayn 2025-03-10 14:08:55 +07:00
parent 2119fd2293
commit 19ff23b2d6
3 changed files with 453 additions and 1 deletions

View File

@ -41,7 +41,7 @@ export default function DetailArtikel({
alt={article.JudulPost}
className="w-full h-auto rounded-lg mb-6"
/>
<div
<article
className="text-justify prose prose-lg max-w-none"
dangerouslySetInnerHTML={{ __html: article.DescPost }}
/>

View File

@ -0,0 +1,227 @@
import React, { useState } from "react";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Perusahaan } from "@/types/perusahaan";
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination";
import { Link } from "@inertiajs/react";
import { Edit, X } from "lucide-react";
interface DetailHistoryPerusahaanTableProps {
data: Perusahaan[];
itemsPerPage?: number;
}
export function DetailHistoryPerusahaanTable({
data,
itemsPerPage = 20,
}: DetailHistoryPerusahaanTableProps) {
// Pagination state
const [currentPage, setCurrentPage] = useState(1);
const totalPages = Math.ceil(data.length / itemsPerPage);
// Calculate displayed items based on current page
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = Math.min(startIndex + itemsPerPage, data.length);
const currentData = data.slice(startIndex, endIndex);
// Navigation functions
const nextPage = () => {
if (currentPage < totalPages) {
setCurrentPage(currentPage + 1);
}
};
const prevPage = () => {
if (currentPage > 1) {
setCurrentPage(currentPage - 1);
}
};
// Generate page numbers array for pagination
const generatePaginationItems = () => {
let pages = [];
const maxVisiblePages = 5;
if (totalPages <= maxVisiblePages) {
// Show all pages if total pages is less than max visible pages
for (let i = 1; i <= totalPages; i++) {
pages.push(i);
}
} else {
// Always show first page
pages.push(1);
// Calculate start and end of middle pages
let startPage = Math.max(2, currentPage - 1);
let endPage = Math.min(totalPages - 1, currentPage + 1);
// Adjust to show 3 middle pages
if (startPage > 2) {
pages.push(null); // ellipsis
}
for (let i = startPage; i <= endPage; i++) {
pages.push(i);
}
if (endPage < totalPages - 1) {
pages.push(null); // ellipsis
}
// Always show last page
pages.push(totalPages);
}
return pages;
};
return (
<div>
<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-[100px] 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>
<TableHead className="border-r text-center text-white">
Keterangan
</TableHead>
<TableHead className="border-r text-center text-white">
Hapus
</TableHead>
</TableRow>
</TableHeader>
<TableBody className="border-b">
{data.length > 0 ? (
currentData.map((perusahaan, index) => (
<TableRow
key={perusahaan.PerusahaanId || index}
className="border-b"
>
<TableCell className="font-medium text-center border-r border-l">
{startIndex + index + 1}
</TableCell>
<TableCell className="items-center justify-center border-r border-l">
<div className="flex justify-center">
{perusahaan.NomorHistory || "-"}
</div>
</TableCell>
<TableCell className="flex items-center justify-center">
{perusahaan.TanggalHistory || "-"}
</TableCell>
<TableCell className="text-center border-r border-l">
{perusahaan.HistoryKegiatan || "-"}
</TableCell>
<TableCell className="text-center border-r border-l">
{perusahaan.KeteranganHistory || "-"}
</TableCell>
<TableCell className="text-center border-r border-l">
{perusahaan.DokumenHistory || "-"}
</TableCell>
<TableCell className="text-center border-r border-l">
<X className="h-5 w-5 text-red-500" />
</TableCell>
</TableRow>
))
) : (
<TableRow>
<TableCell
colSpan={5}
className="h-24 text-center"
>
Tidak ada data
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
{/* Pagination using shadcn/ui */}
{data.length > 0 && totalPages > 1 && (
<div className="mt-4 flex flex-col md:flex-row items-center justify-between">
{/* <div className="text-sm text-gray-500">
Menampilkan {startIndex + 1}-{endIndex} dari{" "}
{data.length} data
</div> */}
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious
onClick={prevPage}
className={
currentPage === 1
? "pointer-events-none opacity-50"
: "cursor-pointer"
}
/>
</PaginationItem>
{generatePaginationItems().map((page, i) =>
page === null ? (
<PaginationItem key={`ellipsis-${i}`}>
<PaginationEllipsis />
</PaginationItem>
) : (
<PaginationItem key={`page-${page}`}>
<PaginationLink
isActive={page === currentPage}
onClick={() => setCurrentPage(page)}
>
{page}
</PaginationLink>
</PaginationItem>
)
)}
<PaginationItem>
<PaginationNext
onClick={nextPage}
className={
currentPage === totalPages
? "pointer-events-none opacity-50"
: "cursor-pointer"
}
/>
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)}
</div>
);
}

View File

@ -0,0 +1,225 @@
import React, { useState } from "react";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Perusahaan } from "@/types/perusahaan";
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination";
import { Link } from "@inertiajs/react";
import { Edit } from "lucide-react";
interface HistoryPerusahaanTableProps {
data: Perusahaan[];
itemsPerPage?: number;
}
export function HistoryPerusahaanTable({
data,
itemsPerPage = 20,
}: HistoryPerusahaanTableProps) {
// Pagination state
const [currentPage, setCurrentPage] = useState(1);
const totalPages = Math.ceil(data.length / itemsPerPage);
// Calculate displayed items based on current page
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = Math.min(startIndex + itemsPerPage, data.length);
const currentData = data.slice(startIndex, endIndex);
// Navigation functions
const nextPage = () => {
if (currentPage < totalPages) {
setCurrentPage(currentPage + 1);
}
};
const prevPage = () => {
if (currentPage > 1) {
setCurrentPage(currentPage - 1);
}
};
// Generate page numbers array for pagination
const generatePaginationItems = () => {
let pages = [];
const maxVisiblePages = 5;
if (totalPages <= maxVisiblePages) {
// Show all pages if total pages is less than max visible pages
for (let i = 1; i <= totalPages; i++) {
pages.push(i);
}
} else {
// Always show first page
pages.push(1);
// Calculate start and end of middle pages
let startPage = Math.max(2, currentPage - 1);
let endPage = Math.min(totalPages - 1, currentPage + 1);
// Adjust to show 3 middle pages
if (startPage > 2) {
pages.push(null); // ellipsis
}
for (let i = startPage; i <= endPage; i++) {
pages.push(i);
}
if (endPage < totalPages - 1) {
pages.push(null); // ellipsis
}
// Always show last page
pages.push(totalPages);
}
return pages;
};
return (
<div>
<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-[100px] border-r border-l text-center text-white">
No.
</TableHead>
<TableHead className="border-r text-center text-white">
Nomor Perusahaan
</TableHead>
<TableHead className="border-r text-center text-white">
Nama Perusahaan
</TableHead>
<TableHead className="border-r text-center text-white">
Alamat
</TableHead>
<TableHead className="border-r text-center text-white">
Kota
</TableHead>
</TableRow>
</TableHeader>
<TableBody className="border-b">
{data.length > 0 ? (
currentData.map((perusahaan, index) => (
<TableRow
key={perusahaan.PerusahaanId || index}
className="border-b"
>
<TableCell className="font-medium text-center border-r border-l">
{startIndex + index + 1}
</TableCell>
<TableCell className="items-center justify-center border-r border-l">
<div className="flex justify-center">
<Link
href={`/admin/history_perusahaan/detail/${perusahaan.PerusahaanId}`}
className="px-2 py-1 bg-blue-100 h-auto font-normal hover:underline text-center flex items-center gap-1 rounded-md"
>
<Edit className="h-3 w-3 text-blue-500" />
{perusahaan.NomorInduk || "-"}
</Link>
</div>
</TableCell>
<TableCell className="flex items-center justify-center">
<Link
href={`/admin/history_perusahaan/detail/${perusahaan.PerusahaanId}`}
className="px-2 py-1 bg-blue-100 h-auto font-normal hover:underline text-center flex items-center gap-1 rounded-md"
>
<Edit className="h-3 w-3 text-blue-500" />
{perusahaan.NamaPerusahaan || "-"}
</Link>
</TableCell>
<TableCell className="text-center border-r border-l">
{perusahaan.Alamat || "-"}
</TableCell>
<TableCell className="text-center border-r border-l">
{perusahaan.kelurahan?.kecamatan
?.kabupaten?.NamaKabupaten || "-"}
</TableCell>
</TableRow>
))
) : (
<TableRow>
<TableCell
colSpan={5}
className="h-24 text-center"
>
Tidak ada data
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
{/* Pagination using shadcn/ui */}
{data.length > 0 && totalPages > 1 && (
<div className="mt-4 flex flex-col md:flex-row items-center justify-between">
{/* <div className="text-sm text-gray-500">
Menampilkan {startIndex + 1}-{endIndex} dari{" "}
{data.length} data
</div> */}
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious
onClick={prevPage}
className={
currentPage === 1
? "pointer-events-none opacity-50"
: "cursor-pointer"
}
/>
</PaginationItem>
{generatePaginationItems().map((page, i) =>
page === null ? (
<PaginationItem key={`ellipsis-${i}`}>
<PaginationEllipsis />
</PaginationItem>
) : (
<PaginationItem key={`page-${page}`}>
<PaginationLink
isActive={page === currentPage}
onClick={() => setCurrentPage(page)}
>
{page}
</PaginationLink>
</PaginationItem>
)
)}
<PaginationItem>
<PaginationNext
onClick={nextPage}
className={
currentPage === totalPages
? "pointer-events-none opacity-50"
: "cursor-pointer"
}
/>
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)}
</div>
);
}