"use client"; import type { ReactNode } from "react"; import { useEffect, useRef, useState } from "react"; import { groupMapLocations } from "@/lib/user-location-map"; import type { UserMapLocation } from "./user-world-map"; export function MapViewToggle({ locations, children }: { locations: UserMapLocation[]; children: ReactNode }) { const [view, setView] = useState<"overview" | "interactive">("overview"); return (

Selecting the interactive view requests map tiles from OpenStreetMap, which receives your IP address, the portal origin, and the geographic area being viewed.

); } function InteractiveMap({ locations }: { locations: UserMapLocation[] }) { const container = useRef(null); useEffect(() => { if (!container.current) return; let cancelled = false; let cleanup = () => {}; void import("leaflet").then((leaflet) => { if (cancelled || !container.current) return; const map = leaflet.map(container.current, { minZoom: 1, worldCopyJump: true }).setView([20, 0], 2); leaflet.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { attribution: '© OpenStreetMap contributors', maxZoom: 19, referrerPolicy: "strict-origin-when-cross-origin", }).addTo(map); const bounds: [number, number][] = []; for (const group of groupMapLocations(locations)) { const firstUser = group.locations[0]!; const isGrouped = group.count > 1; const marker = isGrouped ? leaflet.marker([group.latitude, group.longitude], { icon: leaflet.divIcon({ className: "map-user-cluster", html: ``, iconAnchor: [18, 18], iconSize: [36, 36], }), keyboard: true, }).addTo(map) : leaflet.circleMarker([group.latitude, group.longitude], { radius: 8, color: "#eee8d8", weight: 3, fillColor: "#a32f1b", fillOpacity: 1, }).addTo(map); const tooltip = document.createElement("span"); tooltip.textContent = isGrouped ? `${group.count} users · ${group.nicknames.join(" · ")}` : `${firstUser.nickname} · ${firstUser.location}`; marker.bindTooltip(tooltip, { direction: "top" }); if (isGrouped) { const popup = document.createElement("div"); const heading = document.createElement("strong"); heading.textContent = `${group.count} users near ${firstUser.location}`; popup.append(heading); const list = document.createElement("ul"); for (const user of group.locations) { const item = document.createElement("li"); const link = document.createElement("a"); link.href = `/admin/users/${user.userId}`; link.textContent = user.nickname; item.append(link); list.append(item); } popup.append(list); marker.bindPopup(popup); } else { marker.on("click", () => window.location.assign(`/admin/users/${firstUser.userId}`)); } const element = marker.getElement(); const label = isGrouped ? `${group.count} users near ${firstUser.location}: ${group.nicknames.join(", ")}` : `${firstUser.nickname}, ${firstUser.location}`; element?.setAttribute("aria-label", label); element?.setAttribute("role", isGrouped ? "button" : "link"); element?.setAttribute("tabindex", "0"); if (isGrouped) { element?.setAttribute("aria-haspopup", "dialog"); element?.setAttribute("aria-expanded", "false"); marker.on("popupopen", () => element?.setAttribute("aria-expanded", "true")); marker.on("popupclose", () => element?.setAttribute("aria-expanded", "false")); } element?.addEventListener("focus", () => marker.openTooltip()); element?.addEventListener("blur", () => marker.closeTooltip()); element?.addEventListener("keydown", (event) => { const keyboardEvent = event as KeyboardEvent; if (keyboardEvent.key === "Enter" || keyboardEvent.key === " ") { keyboardEvent.preventDefault(); if (isGrouped) marker.openPopup(); else window.location.assign(`/admin/users/${firstUser.userId}`); } }); bounds.push([group.latitude, group.longitude]); } if (bounds.length) map.fitBounds(bounds, { padding: [40, 40], maxZoom: 6 }); cleanup = () => map.remove(); }); return () => { cancelled = true; cleanup(); }; }, [locations]); return
; }