From e38c5fed44135a41e00c425faee6cf2842f1637f Mon Sep 17 00:00:00 2001 From: Maurice Date: Wed, 15 Apr 2026 22:54:23 +0200 Subject: [PATCH] feat: add uncategorized filter option to category dropdown Add a "No Category" option to the category filter dropdown in the places sidebar, allowing users to filter for places without an assigned category. The filter is synced with the map view. Closes #607 --- .../src/components/Planner/PlacesSidebar.tsx | 31 +++++++++++++++++-- client/src/pages/TripPlannerPage.tsx | 6 +++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/client/src/components/Planner/PlacesSidebar.tsx b/client/src/components/Planner/PlacesSidebar.tsx index 79f27b10..8fa69663 100644 --- a/client/src/components/Planner/PlacesSidebar.tsx +++ b/client/src/components/Planner/PlacesSidebar.tsx @@ -147,7 +147,11 @@ const PlacesSidebar = React.memo(function PlacesSidebar({ const filtered = useMemo(() => places.filter(p => { if (filter === 'unplanned' && plannedIds.has(p.id)) return false - if (categoryFilters.size > 0 && !categoryFilters.has(String(p.category_id))) return false + if (categoryFilters.size > 0) { + if (p.category_id == null) { + if (!categoryFilters.has('uncategorized')) return false + } else if (!categoryFilters.has(String(p.category_id))) return false + } if (search && !p.name.toLowerCase().includes(search.toLowerCase()) && !(p.address || '').toLowerCase().includes(search.toLowerCase())) return false return true @@ -257,7 +261,7 @@ const PlacesSidebar = React.memo(function PlacesSidebar({ const label = categoryFilters.size === 0 ? t('places.allCategories') : categoryFilters.size === 1 - ? categories.find(c => categoryFilters.has(String(c.id)))?.name || t('places.allCategories') + ? (categoryFilters.has('uncategorized') ? t('places.noCategory') : categories.find(c => categoryFilters.has(String(c.id)))?.name || t('places.allCategories')) : `${categoryFilters.size} ${t('places.categoriesSelected')}` return (
@@ -300,6 +304,29 @@ const PlacesSidebar = React.memo(function PlacesSidebar({ ) })} + {places.some(p => p.category_id == null) && (() => { + const active = categoryFilters.has('uncategorized') + return ( + + ) + })()} {categoryFilters.size > 0 && (