satupeta-main/app/(modules)/admin/mapset-upload/_components/map/TablePreview.tsx

163 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import React from "react";
interface TableProps {
title: string;
columns: string[];
rows: any[];
total: number;
limit?: number;
variant?: "preview" | "warning";
}
function Table({ title, columns, rows, total, limit = 100, variant = "preview" }: TableProps) {
const displayedRows = rows.slice(0, limit);
const shorten = (text: any, max = 80) => {
if (!text) return "—";
const strText = String(text);
return strText.length > max ? strText.slice(0, max) + "..." : strText;
};
return (
<div className="w-full">
<div className="overflow-x-auto border border-gray-200 rounded-lg shadow-sm bg-white">
<table className="min-w-max text-sm text-gray-800 w-full">
<thead
className={`border-b ${
variant === "warning" ? "bg-red-50" : "bg-gray-100"
}`}
>
<tr>
{columns.map((col) => (
<th
key={col}
className="px-4 py-3 text-left font-medium text-gray-700 whitespace-nowrap"
>
{col}
</th>
))}
</tr>
</thead>
<tbody>
{displayedRows.length > 0 ? (
displayedRows.map((row, idx) => (
<tr
key={idx}
className={`border-t ${
variant === "warning"
? "bg-red-50/50 hover:bg-red-100/50"
: "even:bg-gray-50 hover:bg-blue-50"
} transition-colors`}
>
{columns.map((col) => (
<td
key={col}
className="px-4 py-2 border-t border-gray-100 whitespace-nowrap max-w-[250px] overflow-hidden text-ellipsis"
title={String(row[col] ?? "")}
>
{row[col] !== null && row[col] !== undefined && row[col] !== "" ? (
col === "geometry" ? (
shorten(row[col], 50)
) : (
shorten(row[col], 80)
)
) : (
<span className="text-gray-300"></span>
)}
</td>
))}
</tr>
))
) : (
<tr>
<td
colSpan={columns.length}
className="text-center text-gray-500 py-6 italic"
>
Tidak ada data yang dapat ditampilkan
</td>
</tr>
)}
</tbody>
</table>
</div>
<div className="flex justify-between items-center px-1 py-2 text-xs text-gray-500">
<p>
Menampilkan {Math.min(limit, displayedRows.length)} dari {total} baris.
</p>
{variant === "preview" && (
<p className="italic text-gray-400">
Hanya menampilkan cuplikan data
</p>
)}
</div>
</div>
);
}
interface TablePreviewProps {
result: {
columns?: string[];
preview?: any[];
geometry_valid?: number;
geometry_empty?: number;
warning_rows?: any[];
[key: string]: any;
} | null;
}
export default function TablePreview({ result }: TablePreviewProps) {
if (!result) return null;
const {
columns = [],
preview = [],
geometry_valid = 0,
geometry_empty = 0,
warning_rows = [],
} = result;
return (
<div className="w-full space-y-6">
{/* 1. WARNING TABLE (Jika ada data yang tidak valid geometrinya) */}
{warning_rows?.length > 0 && (
<div className="border-l-4 border-yellow-400 pl-4 py-2 bg-yellow-50 rounded-r-lg">
<h3 className="font-semibold text-yellow-800 mb-1">
Periksa Data Wilayah
</h3>
<p className="text-sm text-yellow-700 mb-3">
Sistem tidak dapat mendeteksi geometri untuk data di bawah ini. Pastikan nama wilayah sesuai referensi.
</p>
<Table
title="Data Perlu Diperiksa"
columns={columns}
rows={warning_rows}
total={geometry_empty}
limit={100}
variant="warning"
/>
</div>
)}
{/* 2. PREVIEW TABLE (Data Valid) */}
<div>
{geometry_valid > 0 ? (
<Table
title="Cuplikan Data"
columns={columns}
rows={preview}
total={geometry_valid}
limit={10} // Tampilkan 10 baris saja agar tidak terlalu panjang
variant="preview"
/>
) : (
!warning_rows?.length && <div className="text-gray-500 italic">Tidak ada data preview tersedia.</div>
)}
</div>
</div>
);
}