88 lines
3.3 KiB
TypeScript
Executable File
88 lines
3.3 KiB
TypeScript
Executable File
// app/admin/upload/_components/step-3-table-picker.tsx
|
|
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { useUploadContext } from "../_context/upload-context";
|
|
import uploadApi from "@/shared/services/map-upload";
|
|
import { Button } from "@/shared/components/ui/button";
|
|
import { toast } from "sonner";
|
|
|
|
export default function StepTablePicker() {
|
|
const { state, setState, goToStep } = useUploadContext();
|
|
const [selectedTableIdx, setSelectedTableIdx] = useState<number | null>(0);
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const tables = state.result?.data.tables || [];
|
|
const activeTable = selectedTableIdx !== null ? tables[selectedTableIdx] : null;
|
|
|
|
const handleNext = async () => {
|
|
if (!activeTable) return;
|
|
setLoading(true);
|
|
try {
|
|
// Kirim tabel yang dipilih kembali ke backend untuk diproses final
|
|
const res = await uploadApi.processPdf(activeTable, state.file?.name || "doc.pdf", state.fileDesc);
|
|
|
|
setState(prev => ({ ...prev, result: res })); // Update result dengan hasil final (metadata, preview, dll)
|
|
goToStep("VALIDATE", { replace: true });
|
|
} catch (err: any) {
|
|
toast.error(err.message || "Gagal memproses tabel");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="flex h-full gap-4">
|
|
{/* Sidebar List Tabel */}
|
|
<div className="w-64 border-r pr-4">
|
|
<h3 className="font-semibold mb-3">Daftar Tabel Terdeteksi</h3>
|
|
<div className="space-y-2">
|
|
{tables.map((t: any, idx: number) => (
|
|
<div
|
|
key={idx}
|
|
onClick={() => setSelectedTableIdx(idx)}
|
|
className={`p-3 rounded border cursor-pointer text-sm ${
|
|
selectedTableIdx === idx ? "bg-blue-50 border-blue-500" : "bg-white hover:bg-gray-50"
|
|
}`}
|
|
>
|
|
Tabel {t.title || idx + 1}
|
|
</div>
|
|
))}
|
|
</div>
|
|
<Button onClick={handleNext} disabled={loading} className="w-full mt-4">
|
|
{loading ? "Memproses..." : "Proses Tabel →"}
|
|
</Button>
|
|
</div>
|
|
|
|
{/* Preview Data Tabel */}
|
|
<div className="flex-1 overflow-auto border rounded bg-white p-4">
|
|
{activeTable ? (
|
|
<div className="overflow-x-auto">
|
|
<table className="min-w-full text-xs border-collapse border">
|
|
<thead className="bg-gray-100">
|
|
<tr>
|
|
{activeTable.columns?.map((col: string, i: number) => (
|
|
<th key={i} className="border p-2 text-left">{col}</th>
|
|
))}
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{/* {activeTable.rows?.slice(0, 20).map((row: any[], i: number) => ( */}
|
|
{activeTable.rows?.map((row: any[], i: number) => (
|
|
<tr key={i} className="hover:bg-gray-50">
|
|
{activeTable.columns?.map((_: any, colIdx: number) => (
|
|
<td key={colIdx} className="border p-2">{row[colIdx]}</td>
|
|
))}
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
{/* <p className="text-xs text-gray-500 mt-2">Menampilkan 20 baris pertama.</p> */}
|
|
</div>
|
|
) : (
|
|
<div className="text-center text-gray-400 mt-10">Pilih tabel untuk melihat preview</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
} |