diff --git a/frontend/src/components/maps/LocationMapBottomSheet.jsx b/frontend/src/components/maps/LocationMapBottomSheet.jsx index 05cfb7a..e31dd5b 100644 --- a/frontend/src/components/maps/LocationMapBottomSheet.jsx +++ b/frontend/src/components/maps/LocationMapBottomSheet.jsx @@ -2,22 +2,17 @@ import { useMemo } from "react"; import { DEFAULT_MAP_FILTERS, getMapObjectDisplayLabel, + objectZoneId, } from "../../lib/locationMapUtils"; +import { + LocationMapLayerPanel, + LocationMapOverview, + MAP_DISPLAY_CONTROLS, + SelectedMapObjectForm, + SelectedZoneItemsPanel, + UnmappedItemsPanel, +} from "./LocationMapBottomSheetSections"; -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", "Bought"], - ["showUnmapped", "Unmapped"], -]; const EMPTY_ITEMS = []; export default function LocationMapBottomSheet({ @@ -87,7 +82,7 @@ export default function LocationMapBottomSheet({ const showEditorControls = mode === "edit" && canManage; const showSelectedObjectForm = Boolean(mode === "edit" && editorTool === "edit" && selectedObject); const changedLayerCount = useMemo( - () => DISPLAY_CONTROLS.filter(([key]) => filters[key] !== DEFAULT_MAP_FILTERS[key]).length, + () => MAP_DISPLAY_CONTROLS.filter(([key]) => filters[key] !== DEFAULT_MAP_FILTERS[key]).length, [filters] ); const totalAreaCount = mapObjects.length; @@ -102,11 +97,6 @@ export default function LocationMapBottomSheet({ [mapObjects] ); const showDraftOverview = mode === "edit" && editorTool === "edit" && !selectedObject; - const unmappedItemPreview = useMemo( - () => visibleUnmappedItems.slice(0, 8), - [visibleUnmappedItems] - ); - const overflowUnmappedItemCount = visibleUnmappedItems.length - unmappedItemPreview.length; const hiddenUnmappedItemCount = Math.max(0, unmappedItemCount - visibleUnmappedItems.length); const hasHiddenUnmappedItems = filters.showUnmapped && unmappedItemCount > 0 && visibleUnmappedItems.length === 0; @@ -211,23 +201,7 @@ export default function LocationMapBottomSheet({ {layersOpen ? ( -
-
- {DISPLAY_CONTROLS.map(([key, label]) => ( - - ))} -
-
+ ) : null} {showSelectedObjectForm && primaryDraftActions ? ( @@ -249,128 +223,46 @@ export default function LocationMapBottomSheet({ ) : null} {showMapOverview ? ( -
-
- Areas - {filters.showZones ? `${visibleAreaCount} shown` : "Hidden"} -
-
- Mapped items - {mappedItemSummary} -
-
- Unmapped - {unmappedItemSummary} -
-
+ ) : null} {showDraftOverview ? ( -
-
- Areas - {totalAreaCount} -
-
- Hidden - {hiddenAreaCount} -
-
- Unlinked - {unlinkedAreaCount} -
-
+ ) : null} {mode === "edit" && editorTool === "edit" && selectedObject ? ( -
- - -
- - -
-
- - -
-
+ ) : mode === "edit" ? ( null ) : selectedObject ? ( -
- {selectedZoneItems.length === 0 ? ( -
-

- {hasHiddenSelectedItems - ? "Items are assigned here, but hidden by layer filters." - : "No items assigned to this zone yet."} -

- {hasHiddenSelectedItems ? ( - - ) : null} -
- ) : ( - <> -
    - {selectedZoneItems.map((item) => ( -
  • - {item.item_name} - x{item.quantity} -
  • - ))} -
- {hasHiddenSelectedItems ? ( -
-

- {hiddenSelectedItemCount} more hidden by layer filters. -

- -
- ) : null} - - )} -
+ ) : null} {showSelectedObjectForm && secondaryDraftActions ? ( @@ -383,45 +275,13 @@ export default function LocationMapBottomSheet({ ) : null} - {filters.showUnmapped && visibleUnmappedItems.length > 0 ? ( -
- Unmapped Items -
    - {unmappedItemPreview.map((item) => ( -
  • {item.item_name}
  • - ))} - {overflowUnmappedItemCount > 0 ? ( -
  • - +{overflowUnmappedItemCount} more -
  • - ) : null} -
- {hiddenUnmappedItemCount > 0 ? ( -
-

- {hiddenUnmappedItemCount} more hidden by layer filters. -

- -
- ) : null} -
- ) : hasHiddenUnmappedItems ? ( -
- Unmapped Items -
-

- Unmapped items are hidden by layer filters. -

- -
-
+ {filters.showUnmapped ? ( + ) : null} ); diff --git a/frontend/src/components/maps/LocationMapBottomSheetSections.jsx b/frontend/src/components/maps/LocationMapBottomSheetSections.jsx new file mode 100644 index 0000000..e300aa7 --- /dev/null +++ b/frontend/src/components/maps/LocationMapBottomSheetSections.jsx @@ -0,0 +1,218 @@ +import { objectZoneId } from "../../lib/locationMapUtils"; + +export const MAP_DISPLAY_CONTROLS = [ + ["showZones", "Zones"], + ["showLabels", "Labels"], + ["showCounts", "Counts"], + ["showPins", "Pins"], + ["showMyItems", "Mine"], + ["showOtherItems", "Others"], + ["showCompleted", "Bought"], + ["showUnmapped", "Unmapped"], +]; + +const UNMAPPED_PREVIEW_LIMIT = 8; + +export function LocationMapLayerPanel({ filters, setFilters }) { + return ( +
+
+ {MAP_DISPLAY_CONTROLS.map(([key, label]) => ( + + ))} +
+
+ ); +} + +export function LocationMapOverview({ ariaLabel, rows }) { + return ( +
+ {rows.map((row) => ( +
+ {row.label} + {row.value} +
+ ))} +
+ ); +} + +export function SelectedMapObjectForm({ + selectedObject, + zones = [], + saving, + onObjectField, + onZoneLinkChange, + onDuplicateObject, + onDeleteObject, +}) { + return ( +
+ + +
+ + +
+
+ + +
+
+ ); +} + +export function SelectedZoneItemsPanel({ + selectedZoneItems, + hasHiddenSelectedItems, + hiddenSelectedItemCount, + onShowSelectedZoneItems, +}) { + if (selectedZoneItems.length === 0) { + return ( +
+
+

+ {hasHiddenSelectedItems + ? "Items are assigned here, but hidden by layer filters." + : "No items assigned to this zone yet."} +

+ {hasHiddenSelectedItems ? ( + + ) : null} +
+
+ ); + } + + return ( +
+
    + {selectedZoneItems.map((item) => ( +
  • + {item.item_name} + x{item.quantity} +
  • + ))} +
+ {hasHiddenSelectedItems ? ( +
+

+ {hiddenSelectedItemCount} more hidden by layer filters. +

+ +
+ ) : null} +
+ ); +} + +export function UnmappedItemsPanel({ + visibleUnmappedItems, + hiddenUnmappedItemCount, + hasHiddenUnmappedItems, + onShowUnmappedItems, +}) { + if (visibleUnmappedItems.length === 0 && hasHiddenUnmappedItems) { + return ( +
+ Unmapped Items +
+

+ Unmapped items are hidden by layer filters. +

+ +
+
+ ); + } + + if (visibleUnmappedItems.length === 0) { + return null; + } + + const unmappedItemPreview = visibleUnmappedItems.slice(0, UNMAPPED_PREVIEW_LIMIT); + const overflowUnmappedItemCount = visibleUnmappedItems.length - unmappedItemPreview.length; + + return ( +
+ Unmapped Items +
    + {unmappedItemPreview.map((item) => ( +
  • {item.item_name}
  • + ))} + {overflowUnmappedItemCount > 0 ? ( +
  • + +{overflowUnmappedItemCount} more +
  • + ) : null} +
+ {hiddenUnmappedItemCount > 0 ? ( +
+

+ {hiddenUnmappedItemCount} more hidden by layer filters. +

+ +
+ ) : null} +
+ ); +}