satupeta-main/app/(modules)/admin/mapset-upload/_components/step-4-validate.tsx

141 lines
6.1 KiB
TypeScript

"use client";
import { useState, useEffect } from "react";
import dynamic from "next/dynamic"; // ⬅️ PENTING
import { useUploadContext } from "../_context/upload-context";
import { Button } from "@/shared/components/ui/button";
import MetadataForm, { getInitialMetadata } from "./map/MetadataForm";
import TablePreview from "./map/TablePreview";
import { log } from "node:console";
import uploadApi from "@/shared/services/map-upload";
import { useUploadLogic } from "../_hooks/use-upload";
import { toast } from "sonner";
// 🔥 IMPORT DYNAMIC UNTUK KOMPONEN PETA
const SpatialStylePreview = dynamic(() => import("./map/StylePreview"), {
ssr: false,
loading: () => <div className="h-[400px] bg-slate-100 flex items-center justify-center">Loading Map...</div>
});
const StylingLayers = dynamic(() => import("./map/StylingLayers"), {
ssr: false
});
export default function StepValidate() {
const { state, setState, goToStep } = useUploadContext();
const {
loading,
handleSaveToDatabase
} = useUploadLogic();
// State lokal untuk Metadata & Style
// const [metadata, setMetadata] = useState(state.result?.data.metadata_suggest || {});
const [metadata, setMetadata] = useState(() =>
getInitialMetadata(state.result?.data.metadata_suggest || {})
);
const [styleConfig, setStyleConfig] = useState({"styleType": "sld","sldContent": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<StyledLayerDescriptor version=\"1.0.0\"\n xmlns=\"http://www.opengis.net/sld\"\n xmlns:ogc=\"http://www.opengis.net/ogc\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n xmlns:se=\"http://www.opengis.net/se\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:schemaLocation=\"http://www.opengis.net/sld\n http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd\">\n\n <NamedLayer>\n <Name>layer</Name>\n <UserStyle>\n <FeatureTypeStyle>\n <Rule>\n \n <PolygonSymbolizer>\n <Fill>\n <CssParameter name=\"fill\">#3388ff</CssParameter>\n <CssParameter name=\"fill-opacity\">0.5</CssParameter>\n </Fill>\n <Stroke>\n <CssParameter name=\"stroke\">#232323</CssParameter>\n <CssParameter name=\"stroke-width\">1</CssParameter>\n </Stroke>\n </PolygonSymbolizer>\n \n </Rule>\n </FeatureTypeStyle>\n </UserStyle>\n </NamedLayer>\n</StyledLayerDescriptor>\n"});
// Ambil dummy geosStyle atau fetch dari API
const geosStyle = [{name: "Style A"}, {name: "Style B"}];
// const handleConfirm = async () => {
// const table = state.result?.data;
// const data = {
// title: metadata.title,
// columns: table.columns,
// rows: table.preview,
// author: metadata,
// style: styleConfig.sldContent
// }
// handleSaveToDatabase
// // Gabungkan metadata + style + data result -> Kirim ke API saveToDatabase
// // goToStep("SUCCESS");
// };
const handleConfirm = async () => {
// Validasi Frontend
if (!metadata.title) {
toast.warning("Judul data wajib diisi.");
return;
}
const table = state.result?.data;
const data = {
title: metadata.title,
columns: table.columns,
rows: table.preview,
author: metadata,
style: styleConfig.sldContent
}
await handleSaveToDatabase(data);
};
return (
<div className="h-full flex flex-col gap-6">
<h2 className="text-xl font-bold">Validasi & Styling</h2>
<div className="grid grid-cols-1 lg:grid-cols-12 gap-6">
{/* Bagian Peta Preview */}
<div className="lg:col-span-8 h-[500px] border rounded-lg overflow-hidden relative">
<SpatialStylePreview
data={state.result?.data.preview || []}
styleConfig={styleConfig}
/>
</div>
{/* Bagian Kontrol Style */}
<div className="lg:col-span-4 h-[500px] border rounded-lg p-2">
<StylingLayers
data={state.result?.data.preview}
geometryType={state.result?.data.geometry_type}
onSubmit={setStyleConfig}
geosStyle={geosStyle}
/>
</div>
</div>
{/* Bagian Metadata */}
<div className="">
<h3 className="font-bold mb-4">{state.result?.data.file_name}</h3>
{/* <MetadataForm
initialValues={metadata}
onChange={setMetadata}
/> */}
<div className="grid grid-cols-1 lg:grid-cols-12 gap-6">
{/* Bagian Tabel Preview */}
<div className="lg:col-span-8 h-[500px] border rounded-lg p-0">
<h4 className="font-bold m-2">Cuplikan Data</h4>
{/* <SpatialStylePreview
data={state.result?.data.preview || []}
styleConfig={styleConfig}
/> */}
<TablePreview result={state.result?.data} />
</div>
{/* Bagian Info Dataset */}
<div className="lg:col-span-4 h-[500px] border rounded-lg p-2">
<div className="mb-2 flex align-center justify-between">
<h4 className="m-0 font-bold">Info Dataset</h4>
<h4 className="m-0 text-gray-500 italic"><span className="text-red-500">*</span>AI Generate</h4>
</div>
<MetadataForm
initialValues={metadata}
// onChange={setMetadata}
onChange={(updatedData) => setMetadata(updatedData)}
/>
</div>
</div>
</div>
<div className="flex justify-end gap-3 mt-4 pb-10">
<Button variant="outline" onClick={() => goToStep("UPLOAD")}>Batal</Button>
<Button onClick={handleConfirm} disabled={loading}>
{loading ? "Menyimpan..." : "Simpan & Publikasi"}
</Button>
</div>
</div>
);
}