import { useState } from "react"; import { api } from "../api"; import type { ListedMap } from "../types"; import "./MapListModal.css"; import { FaTrash } from "react-icons/fa6"; function timeAgo(date: Date): string { const diff = Date.now() - new Date(date).getTime(); const minutes = Math.floor(diff / 60_000); if (minutes < 1) return "just now"; if (minutes < 60) return `${minutes}m ago`; const hours = Math.floor(minutes / 60); if (hours < 24) return `${hours}h ago`; const days = Math.floor(hours / 24); if (days < 30) return `${days}d ago`; const months = Math.floor(days / 30); if (months < 12) return `${months}mo ago`; return `${Math.floor(months / 12)}y ago`; } interface Props { maps: ListedMap[]; selectedMapId: string | null; onSelect: (id: string) => void; onClose: () => void; onMapsChange: (maps: ListedMap[]) => void; } /** Copy text to the clipboard; show a brief "Copied!" toast. */ function copyToClipboard( text: string, setCopied: (id: string | null) => void, id: string, ) { navigator.clipboard.writeText(text).then(() => { setCopied(id); setTimeout(() => setCopied(null), 1500); }); } function accessLabel(access: string): string { switch (access) { case "public_view": return "Public (view)"; case "public_edit": return "Public (edit)"; default: return "Private"; } } export default function MapListModal({ maps, selectedMapId, onSelect, onClose, onMapsChange, }: Props) { const [copiedId, setCopiedId] = useState(null); const [togglingId, setTogglingId] = useState(null); async function handleFavoriteToggle(e: React.MouseEvent, map: ListedMap) { e.stopPropagation(); setTogglingId(map.id); try { if (map.is_favorited) { await api.unfavoriteMap(map.id); } else { await api.favoriteMap(map.id); } onMapsChange( maps.map((m) => m.id === map.id ? { ...m, is_favorited: !m.is_favorited } : m, ), ); } catch (err) { console.error("Failed to toggle favorite", err); } finally { setTogglingId(null); } } function handleCopyLink(e: React.MouseEvent, map: ListedMap) { e.stopPropagation(); const link = `${window.location.origin}/map/${encodeURIComponent(map.id)}`; copyToClipboard(link, setCopiedId, map.id); } function handleSelect(map: ListedMap) { onSelect(map.id); onClose(); } return (
e.stopPropagation()} >

Maps

{maps.length === 0 ? (

No maps yet. Click "+ New Map" to create one.

) : (
{[...maps] .sort( (a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime(), ) .map((map) => (
handleSelect(map)} role="button" tabIndex={0} onKeyDown={(e) => e.key === "Enter" && handleSelect(map)} >
{map.name}
by {map.owner_username} {accessLabel(map.public_access)} {map.user_role && ( {map.user_role} )} {map.is_favorited && !map.user_role && ( ★ Favorited )} {timeAgo(map.updated_at)}
{/* Favorite toggle */} {/* Copy link */} {/* Delete map button */}
))}
)}
); }