"use client"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useAtom } from "jotai"; import { useRouter, useParams } from "next/navigation"; import { useEffect } from "react"; import { Loader2 } from "lucide-react"; import { toast } from "sonner"; import categoryApi from "@/shared/services/category"; import classificationApi from "@/shared/services/classification"; import mapProjectionSystemApi from "@/shared/services/map-projection-system"; import organizationApi from "@/shared/services/organization"; import mapSourceApi from "@/shared/services/map-source"; import mapsetApi from "@/shared/services/mapset"; import { MapsetInfoForm } from "../../_components/form/mapset-info-form"; import { MapsetMetadataForm } from "../../_components/form/mapset-metadata-form"; import { MapsetVersionForm } from "../../_components/form/mapset-version-form"; import MapsetTab from "../../_components/form/mapset-tab"; import { PaginatedResponse } from "@/shared/types/api-response"; import { MapsetSubmitPayload } from "@/shared/types/mapset"; import StatusValidation from "@/shared/config/status-validation"; import { activeTabAtom, mapsetFormAtom, MapsetFormState, MapsetFormTab } from "../../state"; import PageHeader from "../../../_components/page-header"; import { MapsetClassificationForm } from "../../_components/form/mapset-classification-form"; import { useAuthSession } from "@/shared/hooks/use-session"; interface SelectOption { id: string; name: string; } export default function EditMapsPageClient() { const router = useRouter(); const params = useParams(); const mapsetId = params.id as string; const queryClient = useQueryClient(); const [activeTab, setActiveTab] = useAtom(activeTabAtom); const [formState, setFormState] = useAtom(mapsetFormAtom); const { session } = useAuthSession(); const isDataManager = session?.user?.role?.name === "data_manager"; const { data: mapset, isLoading: isLoadingMapset, refetch, } = useQuery({ queryKey: ["mapset", mapsetId], queryFn: () => mapsetApi.getMapsetById(mapsetId), enabled: !!mapsetId && !!session?.user, }); useEffect(() => { if (mapsetId && session?.user?.role?.name) { refetch(); } }, [mapsetId, session, refetch]); const { data: projectionSystemsResponse, isLoading: isLoadingProjections } = useQuery({ queryKey: ["projectionSystems"], queryFn: () => mapProjectionSystemApi.getMapProjectionSystems(), staleTime: 5 * 60 * 1000, refetchOnMount: false, enabled: !!session?.user, }); const { data: categoriesResponse, isLoading: isLoadingCategories } = useQuery({ queryKey: ["categories"], queryFn: () => categoryApi.getCategories(), staleTime: 5 * 60 * 1000, refetchOnMount: false, enabled: !!session?.user, }); const { data: classificationsResponse, isLoading: isLoadingClassifications } = useQuery({ queryKey: ["classifications"], queryFn: () => classificationApi.getClassifications(), staleTime: 5 * 60 * 1000, refetchOnMount: false, enabled: !!session?.user, }); const { data: organizationsResponse, isLoading: isLoadingOrganizations } = useQuery({ queryKey: ["organizations"], queryFn: () => organizationApi.getOrganizations(), staleTime: 5 * 60 * 1000, refetchOnMount: false, enabled: !!session?.user, }); const { data: mapSourcesResponse, isLoading: isLoadingMapSources } = useQuery({ queryKey: ["map-sources"], queryFn: () => mapSourceApi.getMapSources(), staleTime: 5 * 60 * 1000, refetchOnMount: false, enabled: !!session?.user, }); useEffect(() => { if (mapset) { const geoserverSource = mapset.sources.find((source) => source.url?.includes("geoserver")); const geonetworkSource = mapset.sources.find((source) => source.url?.includes("geonetwork")); setFormState({ info: { name: mapset.name, description: mapset.description, scale: mapset.scale, projection_system_id: mapset?.projection_system?.id, category_id: mapset?.category?.id, data_status: mapset.data_status, classification_id: mapset?.classification?.id, organization_id: mapset?.producer?.id, is_popular: mapset.is_popular, layer_type: mapset?.layer_type, }, metadata: { source_id: geoserverSource?.id || null, layer_url: mapset.layer_url, metadata_source_id: geonetworkSource?.id || null, metadata_url: mapset.metadata_url, }, classification: { coverage_level: mapset.coverage_level, coverage_area: mapset.coverage_area, }, version: { data_update_period: mapset.data_update_period, data_version: mapset.data_version, }, }); } }, [mapset, setFormState]); useEffect(() => { if (session?.user && !mapset && !isLoadingMapset) { const currentUrl = window.location.pathname + window.location.search; router.replace(currentUrl); } }, [session, mapset, isLoadingMapset, router]); const isLoading = isLoadingMapset || isLoadingProjections || isLoadingCategories || isLoadingClassifications || isLoadingOrganizations || isLoadingMapSources || !projectionSystemsResponse || !categoriesResponse || !classificationsResponse || !organizationsResponse || !mapSourcesResponse; const mapDataToOptions = (response: PaginatedResponse | undefined): SelectOption[] => { if (!response || !response.items) return []; return response.items.map((item) => ({ id: item.id, name: item.name })); }; const projectionSystemOptions = mapDataToOptions(projectionSystemsResponse); const categoryOptions = mapDataToOptions(categoriesResponse); const classificationOptions = mapDataToOptions(classificationsResponse); const organizationOptions = mapDataToOptions(organizationsResponse); const mapSourceOptions = mapDataToOptions(mapSourcesResponse); // eslint-disable-next-line @typescript-eslint/no-explicit-any const updateFormData = (tabKey: keyof MapsetFormState, data: any) => { setFormState({ ...formState, [tabKey]: data, }); }; const handleContinue = () => { if (activeTab < MapsetFormTab.VERSION) { setActiveTab((prev) => prev + 1); } }; const handlePrevious = () => { if (activeTab > MapsetFormTab.INFO) { setActiveTab(activeTab - 1); } }; const updateMapsetMutation = useMutation({ mutationFn: (mapsetData: MapsetSubmitPayload) => { return mapsetApi.updateMapset(mapsetId, mapsetData); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["mapsets"] }); queryClient.invalidateQueries({ queryKey: ["mapset", mapsetId] }); toast.success("Mapset berhasil diperbarui!"); router.push("/admin/mapset"); }, onError: (error: Error) => { toast.error(error.message || "Terjadi kesalahan saat memperbarui data"); }, }); const handleSubmitMapset = (versionData: { data_update_period: string; data_version: string }) => { updateFormData("version", versionData); const payload: MapsetSubmitPayload = { name: formState.info.name, description: formState.info.description, scale: formState.info.scale, projection_system_id: formState.info.projection_system_id, category_id: formState.info.category_id, data_status: formState.info.data_status, classification_id: formState.info.classification_id, producer_id: formState.info.organization_id, layer_type: formState.info.layer_type, source_id: [formState.metadata.source_id, formState.metadata.metadata_source_id].filter((id) => id !== "lainnya" && id !== null) as string[], layer_url: formState.metadata.layer_url, metadata_url: formState.metadata.metadata_url, coverage_level: formState.classification.coverage_level, coverage_area: formState.classification.coverage_area, data_update_period: versionData.data_update_period, data_version: versionData.data_version, is_popular: formState.info.is_popular || false, is_active: mapset?.is_active || true, regional_id: mapset?.regional.id || "01968b53-a910-7a67-bd10-975b8923b92e", status_validation: mapset?.status_validation || StatusValidation.ON_VERIFICATION, }; updateMapsetMutation.mutate(payload); }; if (isLoading || !mapset) { return (

Memuat data...

); } return (
setActiveTab(e)} />
{activeTab === MapsetFormTab.INFO && ( { updateFormData("info", data); handleContinue(); }} /> )} {activeTab === MapsetFormTab.METADATA && ( { updateFormData("metadata", data); handleContinue(); }} onPrevious={handlePrevious} /> )} {activeTab === MapsetFormTab.CLASSIFICATION && ( { updateFormData("classification", data); handleContinue(); }} onPrevious={handlePrevious} /> )} {activeTab === MapsetFormTab.VERSION && ( { updateFormData("version", data); }} /> )}
); }