"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { Loader2, MapPin, Check, X, ExternalLink } from "lucide-react"; // Pin a site on the map. // // Deliberately plain number inputs plus a "open in maps" link, rather than a // drag-to-pin map: the in-app Leaflet map is still being worked on, and a coordinate // entered by hand is usually copied off a map anyway. A point can be pasted straight in. // // Bounds are enforced server-side as well as here — a stray 0,0 or a digit dropped in // the wrong box would otherwise place the marker in the Gulf of Guinea. export function SiteCoordinateEditor({ siteId, name, latitude, longitude, }: { siteId: string; name: string; latitude: number | null; longitude: number | null; }) { const router = useRouter(); const has = Boolean(latitude || longitude); const [open, setOpen] = useState(false); const [lat, setLat] = useState(latitude ? String(latitude) : ""); const [lng, setLng] = useState(longitude ? String(longitude) : ""); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); const [saved, setSaved] = useState(false); async function save(clear = false) { setBusy(true); setError(null); try { const res = await fetch(`/api/sites/${siteId}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify( clear ? { latitude: null, longitude: null } : { latitude: Number(lat), longitude: Number(lng) }, ), }); const data = await res.json().catch(() => ({ ok: false, error: "Unexpected response" })); if (!data.ok) { setError(data.error || "Could not save"); } else { setOpen(false); setSaved(true); setTimeout(() => setSaved(false), 2500); router.refresh(); } } catch { setError("Could not reach the server"); } finally { setBusy(false); } } if (!open) { return (
{has && ( Open in maps )}
); } return (
setLat(e.target.value)} placeholder="-26.101615" className="min-h-[44px] w-full px-3 rounded-lg border border-gray-200 dark:border-white/10 bg-white dark:bg-white/5 text-sm tabular-nums focus:outline-none focus:border-[#30638E]" />
setLng(e.target.value)} placeholder="28.348725" className="min-h-[44px] w-full px-3 rounded-lg border border-gray-200 dark:border-white/10 bg-white dark:bg-white/5 text-sm tabular-nums focus:outline-none focus:border-[#30638E]" />
{error &&

{error}

}
{has && ( )}

Paste a point copied from any map. Only coordinates inside South Africa are accepted.

); }