import { DEFAULT_MAP_FILTERS, MAP_OBJECT_TYPES, getMapObjectDisplayLabel, } from "../../lib/locationMapUtils"; function objectZoneId(object) { return object?.zone_id ? String(object.zone_id) : ""; } const DISPLAY_CONTROLS = [ ["showZones", "Zones"], ["showLabels", "Labels"], ["showCounts", "Counts"], ["showPins", "Pins"], ["showMyItems", "Mine"], ["showOtherItems", "Others"], ["showCompleted", "Done"], ["showUnmapped", "Unmapped"], ]; function formatObjectTypeLabel(type) { return String(type) .split(/[-_\s]+/) .filter(Boolean) .map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`) .join(" "); } export default function LocationMapBottomSheet({ mode, editorTool, canManage, filters, setFilters, layersOpen, setLayersOpen, selectedObject, selectedZoneItems, visibleUnmappedItems, unmappedItemCount, hiddenAreaCount, history, future, saving, savingAction, hasUnsavedChanges, mapState, mapSize, onAddObject, onUndo, onRedo, onSaveDraft, onPublish, onPreviewDraft, onPanMode, onEditObjects, onObjectField, onZoneLinkChange, onClearSelection, onDuplicateObject, onDeleteObject, onShowHiddenAreas, }) { const selectedTitle = getMapObjectDisplayLabel(selectedObject); const selectedAssignedItems = selectedObject?.zone_id ? (mapState?.items || []).filter((item) => String(item.zone_id || "") === objectZoneId(selectedObject)) : []; const hiddenSelectedItemCount = Math.max(0, selectedAssignedItems.length - selectedZoneItems.length); const hasHiddenSelectedItems = hiddenSelectedItemCount > 0; const selectedItemCountLabel = hasHiddenSelectedItems ? `${selectedZoneItems.length} shown` : `${selectedZoneItems.length} item${selectedZoneItems.length === 1 ? "" : "s"}`; const sheetTitle = mode === "edit" ? selectedObject && editorTool === "edit" ? selectedTitle : editorTool === "edit" ? "Edit Objects" : "Pan Mode" : selectedObject ? selectedTitle : "Map Details"; const sheetDescription = selectedObject && editorTool === "edit" ? "Move, resize, link, rename, or nudge with arrow keys." : editorTool === "edit" ? "Tap an area to select it." : "Drag and zoom without changing objects."; const showHeaderItemCount = mode !== "edit" && Boolean(selectedObject); const showEditorControls = mode === "edit" && canManage; const showSelectedObjectForm = Boolean(mode === "edit" && editorTool === "edit" && selectedObject); const changedLayerCount = DISPLAY_CONTROLS.filter(([key]) => filters[key] !== DEFAULT_MAP_FILTERS[key]).length; const unmappedItemPreview = visibleUnmappedItems.slice(0, 8); const overflowUnmappedItemCount = visibleUnmappedItems.length - unmappedItemPreview.length; const hiddenUnmappedItemCount = Math.max(0, unmappedItemCount - visibleUnmappedItems.length); const hasHiddenUnmappedItems = filters.showUnmapped && unmappedItemCount > 0 && visibleUnmappedItems.length === 0; const selectedWidth = Number(selectedObject?.width) || 40; const selectedHeight = Number(selectedObject?.height) || 40; const hiddenAreaLabel = `Show Hidden Areas (${hiddenAreaCount})`; const geometryLocked = Boolean(selectedObject?.locked); const maxX = Math.max(0, Math.round((mapSize?.width || selectedWidth) - selectedWidth)); const maxY = Math.max(0, Math.round((mapSize?.height || selectedHeight) - selectedHeight)); const maxWidth = Math.max(40, Math.round(mapSize?.width || selectedWidth)); const maxHeight = Math.max(40, Math.round(mapSize?.height || selectedHeight)); const saveDraftLabel = savingAction === "save" ? "Saving..." : "Save Draft"; const publishLabel = savingAction === "publish" ? "Publishing..." : "Publish"; const resetLayerFilters = () => setFilters({ ...DEFAULT_MAP_FILTERS }); const showSelectedZoneItems = () => { setFilters((current) => ({ ...current, showMyItems: true, showOtherItems: true, showCompleted: true, })); }; const showUnmappedItems = () => { setFilters((current) => ({ ...current, showUnmapped: true, showMyItems: true, showOtherItems: true, showCompleted: true, })); }; const primaryDraftActions = showEditorControls ? (
) : null; const secondaryDraftActions = showEditorControls ? (
) : null; const editorActions = showEditorControls ? (
{primaryDraftActions} {secondaryDraftActions}
) : null; return ( ); }