diff --git a/client/src/components/Planner/DayPlanSidebar.test.tsx b/client/src/components/Planner/DayPlanSidebar.test.tsx
index 96d3040c3..3806433cd 100644
--- a/client/src/components/Planner/DayPlanSidebar.test.tsx
+++ b/client/src/components/Planner/DayPlanSidebar.test.tsx
@@ -210,6 +210,48 @@ describe('DayPlanSidebar', () => {
expect(screen.queryByRole('button', { name: 'Open in Google Maps' })).not.toBeInTheDocument()
})
+ // ── #1297: route tools for a hotel-to-hotel transfer day with no stops ───────
+ it('FE-PLANNER-DAYPLAN-005d: route tools show for a two-hotel transfer day with no places (#1297)', () => {
+ const dayA = buildDay({ id: 10, date: '2025-06-01', title: 'Day 1' })
+ const dayTransfer = buildDay({ id: 11, date: '2025-06-02', title: 'Day 2' })
+ const dayB = buildDay({ id: 12, date: '2025-06-03', title: 'Day 3' })
+ // Check out of hotel A (slept there) and into hotel B on the same day — two distinct
+ // located hotels, zero places. The map draws A → B, so the tools must be reachable.
+ const accommodations = [
+ { id: 1, start_day_id: 10, end_day_id: 11, place_lat: 48.85, place_lng: 2.35 },
+ { id: 2, start_day_id: 11, end_day_id: 12, place_lat: 51.50, place_lng: -0.12 },
+ ]
+ render( )
+ expect(screen.getByRole('button', { name: 'Open in Google Maps' })).toBeInTheDocument()
+ })
+
+ it('FE-PLANNER-DAYPLAN-005e: no route tools on a same-hotel rest day with no places (#1297 guard)', () => {
+ const dayA = buildDay({ id: 10, date: '2025-06-01', title: 'Day 1' })
+ const dayRest = buildDay({ id: 11, date: '2025-06-02', title: 'Day 2' })
+ const dayC = buildDay({ id: 12, date: '2025-06-03', title: 'Day 3' })
+ // One hotel spanning all three days: the middle day has morning === evening, so there is
+ // no transfer leg to draw and the tools stay hidden.
+ const accommodations = [{ id: 1, start_day_id: 10, end_day_id: 12, place_lat: 48.85, place_lng: 2.35 }]
+ render( )
+ expect(screen.queryByRole('button', { name: 'Open in Google Maps' })).not.toBeInTheDocument()
+ })
+
+ it('FE-PLANNER-DAYPLAN-005f: no route tools on a plain arrival day with no places (#1297 guard)', () => {
+ const dayArrive = buildDay({ id: 11, date: '2025-06-02', title: 'Day 1' })
+ const dayNext = buildDay({ id: 12, date: '2025-06-03', title: 'Day 2' })
+ // Only a check-in today (no hotel slept in last night, no places): morning === evening,
+ // so there is no hotel → hotel leg and the tools stay hidden.
+ const accommodations = [{ id: 2, start_day_id: 11, end_day_id: 12, place_lat: 51.50, place_lng: -0.12 }]
+ render( )
+ expect(screen.queryByRole('button', { name: 'Open in Google Maps' })).not.toBeInTheDocument()
+ })
+
// ── Day expansion/collapse ──────────────────────────────────────────────
it('FE-PLANNER-DAYPLAN-006: days are expanded by default', () => {
diff --git a/client/src/components/Planner/DayPlanSidebar.tsx b/client/src/components/Planner/DayPlanSidebar.tsx
index e9e7dca91..4b91d40d7 100644
--- a/client/src/components/Planner/DayPlanSidebar.tsx
+++ b/client/src/components/Planner/DayPlanSidebar.tsx
@@ -1448,7 +1448,21 @@ const DayPlanSidebar = React.memo(function DayPlanSidebar(props: DayPlanSidebarP
(routeBookends?.morning?.place_lat != null && routeBookends?.morning?.place_lng != null) ||
(routeBookends?.evening?.place_lat != null && routeBookends?.evening?.place_lng != null)
)
- const routeToolsRoutable = da.length >= 2 || (loc != null && hasRouteBookend)
+ // Transfer day with no stops at all: you check out of one hotel and into another, so
+ // the map already draws a hotel → hotel leg (see the transfer branch in
+ // useRouteCalculation) even with zero places. Mirror that exact gate here — two
+ // distinct bookend hotels you actually slept in / sleep in tonight — so the route
+ // tools appear when you click the day (#1297). A same-hotel rest day or a plain
+ // arrival/departure day has morning === evening and stays excluded.
+ const transferMorning = routeBookends?.morning
+ const transferEvening = routeBookends?.evening
+ const hasHotelTransfer = !!(
+ routeBookends?.morningIsSleptHere && routeBookends?.eveningIsOvernight &&
+ transferMorning?.place_lat != null && transferMorning?.place_lng != null &&
+ transferEvening?.place_lat != null && transferEvening?.place_lng != null &&
+ (transferMorning.place_lat !== transferEvening.place_lat || transferMorning.place_lng !== transferEvening.place_lng)
+ )
+ const routeToolsRoutable = da.length >= 2 || (loc != null && hasRouteBookend) || hasHotelTransfer
// Is this day's inline route currently on? Mobile toggles it per day (its
// own expandedRouteDayIds entry); desktop uses the global Route toggle on
// the selected day (#1374).
@@ -2444,7 +2458,7 @@ const DayPlanSidebar = React.memo(function DayPlanSidebar(props: DayPlanSidebarP
)}
- {/* Routen-Werkzeuge (ausgewählter Tag, 2+ Orte — oder 1 Ort mit Hotel-Bookend, #1330) */}
+ {/* Routen-Werkzeuge (ausgewählter Tag, 2+ Orte — oder 1 Ort mit Hotel-Bookend #1330 — oder Hotel-zu-Hotel-Transfertag ohne Orte #1297) */}
{(isSelected || (showRouteToolsWhenExpanded && isExpanded)) && routeToolsRoutable && (
diff --git a/client/src/components/Planner/PlacesSidebar.test.tsx b/client/src/components/Planner/PlacesSidebar.test.tsx
index 94bf45018..3e3118c91 100644
--- a/client/src/components/Planner/PlacesSidebar.test.tsx
+++ b/client/src/components/Planner/PlacesSidebar.test.tsx
@@ -242,6 +242,18 @@ describe('Filter tabs', () => {
await user.click(screen.getByRole('button', { name: /Unplanned/i }));
expect(screen.getByText(/All places are planned/i)).toBeInTheDocument();
});
+
+ it('FE-PLANNER-SIDEBAR-019b: "Planned" filter shows only planned places', () => {
+ const planned = buildPlace({ name: 'Planned Place' });
+ const unplanned = buildPlace({ name: 'Unplanned Place' });
+ const assignments = { '1': [buildAssignment({ place: planned, day_id: 1 })] };
+ // Seed the pool filter directly: the tab label resolves from @trek/shared, but the
+ // filter behaviour (only day-assigned places survive) is what this guards.
+ seedStore(useTripStore, { placesFilter: 'planned' });
+ render(
);
+ expect(screen.getByText('Planned Place')).toBeInTheDocument();
+ expect(screen.queryByText('Unplanned Place')).not.toBeInTheDocument();
+ });
});
// ── Search ────────────────────────────────────────────────────────────────────
diff --git a/client/src/components/Planner/PlacesSidebarHeader.tsx b/client/src/components/Planner/PlacesSidebarHeader.tsx
index daf418f74..a28f653b2 100644
--- a/client/src/components/Planner/PlacesSidebarHeader.tsx
+++ b/client/src/components/Planner/PlacesSidebarHeader.tsx
@@ -86,13 +86,15 @@ export function PlacesHeader(S: SidebarState) {
const counts = {
all: baseFiltered.length,
unplanned: baseFiltered.filter(p => !plannedIds.has(p.id)).length,
+ planned: baseFiltered.filter(p => plannedIds.has(p.id)).length,
tracks: baseFiltered.filter(p => p.route_geometry).length,
}
const tabs = ([
{ id: 'all', label: t('places.all') },
{ id: 'unplanned', label: t('places.unplanned') },
+ { id: 'planned', label: t('places.planned') },
hasTracks ? { id: 'tracks', label: t('places.filterTracks') } : null,
- ] as const).filter(Boolean) as Array<{ id: 'all' | 'unplanned' | 'tracks'; label: string }>
+ ] as const).filter(Boolean) as Array<{ id: 'all' | 'unplanned' | 'planned' | 'tracks'; label: string }>
return (
{tabs.map(f => {
diff --git a/client/src/components/Planner/usePlacesSidebar.ts b/client/src/components/Planner/usePlacesSidebar.ts
index 12a1c8cfa..6dbd04b41 100644
--- a/client/src/components/Planner/usePlacesSidebar.ts
+++ b/client/src/components/Planner/usePlacesSidebar.ts
@@ -201,6 +201,7 @@ export function usePlacesSidebar(props: PlacesSidebarProps) {
const filtered = useMemo(() => {
const list = places.filter(p => {
if (filter === 'unplanned' && plannedIds.has(p.id)) return false
+ if (filter === 'planned' && !plannedIds.has(p.id)) return false
if (filter === 'tracks' && !p.route_geometry) return false
if (categoryFilters.size > 0) {
if (p.category_id == null) {
diff --git a/client/src/mobile/screens/trip/places/MPlacesBrowser.tsx b/client/src/mobile/screens/trip/places/MPlacesBrowser.tsx
index 71a8c4c3b..02301be56 100644
--- a/client/src/mobile/screens/trip/places/MPlacesBrowser.tsx
+++ b/client/src/mobile/screens/trip/places/MPlacesBrowser.tsx
@@ -13,7 +13,7 @@ import type { MPlacesBrowserProps } from '../MTripShell'
import type { Place } from '../../../../types'
import MPlacesBulkCategorySheet from './MPlacesBulkCategorySheet'
import MPlacesSaveToCollectionSheet from './MPlacesSaveToCollectionSheet'
-import { filterPool, firstPlannedDayNumbers, plannedPlaceIds, poolCounts } from './placesBrowserModel'
+import { filterPool, firstPlannedDayNumbers, plannedPlaceIds } from './placesBrowserModel'
/**
* Fullscreen places pool (mode === 'browse'): All/Unplanned/Tracks filter
@@ -56,10 +56,6 @@ export default function MPlacesBrowser({ planner, shell }: MPlacesBrowserProps)
const plannedIds = useMemo(() => plannedPlaceIds(assignments), [assignments])
const dayNumberByPlace = useMemo(() => firstPlannedDayNumbers(assignments, days), [assignments, days])
- const counts = useMemo(
- () => poolCounts(places, categoryFilters, search, plannedIds),
- [places, categoryFilters, search, plannedIds],
- )
const filtered = useMemo(
() => filterPool(places, { filter, categoryFilters, search, plannedIds }),
[places, filter, categoryFilters, search, plannedIds],
@@ -121,38 +117,30 @@ export default function MPlacesBrowser({ planner, shell }: MPlacesBrowserProps)
return (
- {/* ── Filter chips + Add + Import ── */}
+ {/* ── Filter chips + Import (Add sits in the search row below to free space) ── */}
{ setFilter('all'); setSelectedIds(new Set()) }}
/>
{ setFilter('unplanned'); setSelectedIds(new Set()) }}
/>
+ { setFilter('planned'); setSelectedIds(new Set()) }}
+ />
{hasTracks && (
{ setFilter('tracks'); setSelectedIds(new Set()) }}
/>
)}
- {canEditPlaces && (
-
-
- {t('common.add')}
-
- )}
{canEditPlaces && (
: }
)}
+ {canEditPlaces && (
+
+
+
+ )}
{/* ── Selection toolbar ── */}
@@ -359,18 +357,18 @@ export default function MPlacesBrowser({ planner, shell }: MPlacesBrowserProps)
)
}
-/** All / Unplanned / Tracks pool chip with its Geist count. */
-function FilterChip({ active, label, count, onClick }: { active: boolean; label: string; count: number; onClick: () => void }) {
+/** All / Unplanned / Planned / Tracks pool chip. Counts are omitted on mobile to save row
+ * space; chips flex to share the row's full width up to the import button on the right. */
+function FilterChip({ active, label, onClick }: { active: boolean; label: string; onClick: () => void }) {
return (
{label}
- {count}
)
}
diff --git a/client/src/mobile/screens/trip/places/placesBrowserModel.test.ts b/client/src/mobile/screens/trip/places/placesBrowserModel.test.ts
new file mode 100644
index 000000000..6bee97075
--- /dev/null
+++ b/client/src/mobile/screens/trip/places/placesBrowserModel.test.ts
@@ -0,0 +1,40 @@
+import { describe, it, expect } from 'vitest'
+import { filterPool, poolCounts } from './placesBrowserModel'
+import type { Place } from '../../../../types'
+
+const mkPlace = (id: number, over: Partial
= {}): Place =>
+ ({ id, name: `Place ${id}`, lat: 0, lng: 0, address: null, category_id: null, ...over } as Place)
+
+describe('placesBrowserModel — planned pool', () => {
+ const places = [mkPlace(1), mkPlace(2), mkPlace(3)]
+ const plannedIds = new Set([1, 3]) // 1 and 3 are assigned to a day
+ const noCats = new Set()
+
+ it('MOBILE-POOL-planned: keeps only planned places', () => {
+ const out = filterPool(places, { filter: 'planned', categoryFilters: noCats, search: '', plannedIds })
+ expect(out.map(p => p.id)).toEqual([1, 3])
+ })
+
+ it('MOBILE-POOL-unplanned: keeps only unplanned places (unchanged)', () => {
+ const out = filterPool(places, { filter: 'unplanned', categoryFilters: noCats, search: '', plannedIds })
+ expect(out.map(p => p.id)).toEqual([2])
+ })
+
+ it('MOBILE-POOL-all: keeps everything', () => {
+ const out = filterPool(places, { filter: 'all', categoryFilters: noCats, search: '', plannedIds })
+ expect(out.map(p => p.id)).toEqual([1, 2, 3])
+ })
+
+ it('MOBILE-POOL-planned+search: planned pool still honors the search box', () => {
+ const named = [mkPlace(1, { name: 'Louvre' }), mkPlace(3, { name: 'Eiffel' })]
+ const out = filterPool(named, { filter: 'planned', categoryFilters: noCats, search: 'eiff', plannedIds })
+ expect(out.map(p => p.id)).toEqual([3])
+ })
+
+ it('MOBILE-POOL-counts: poolCounts reports planned alongside all/unplanned', () => {
+ const c = poolCounts(places, noCats, '', plannedIds)
+ expect(c.all).toBe(3)
+ expect(c.planned).toBe(2)
+ expect(c.unplanned).toBe(1)
+ })
+})
diff --git a/client/src/mobile/screens/trip/places/placesBrowserModel.ts b/client/src/mobile/screens/trip/places/placesBrowserModel.ts
index 8cfbbc980..1e62c9a76 100644
--- a/client/src/mobile/screens/trip/places/placesBrowserModel.ts
+++ b/client/src/mobile/screens/trip/places/placesBrowserModel.ts
@@ -57,6 +57,7 @@ interface PoolFilterArgs {
export function filterPool(places: Place[], { filter, categoryFilters, search, plannedIds }: PoolFilterArgs): Place[] {
return places.filter(p => {
if (filter === 'unplanned' && plannedIds.has(p.id)) return false
+ if (filter === 'planned' && !plannedIds.has(p.id)) return false
if (filter === 'tracks' && !p.route_geometry) return false
return matchesCategoryFilter(p, categoryFilters) && matchesSearch(p, search)
})
@@ -68,6 +69,7 @@ export function poolCounts(places: Place[], categoryFilters: Set, search
return {
all: base.length,
unplanned: base.filter(p => !plannedIds.has(p.id)).length,
+ planned: base.filter(p => plannedIds.has(p.id)).length,
tracks: base.filter(p => p.route_geometry).length,
}
}
diff --git a/client/src/pages/tripPlanner/useTripPlanner.ts b/client/src/pages/tripPlanner/useTripPlanner.ts
index 08404a57e..485244edc 100644
--- a/client/src/pages/tripPlanner/useTripPlanner.ts
+++ b/client/src/pages/tripPlanner/useTripPlanner.ts
@@ -371,8 +371,9 @@ export function useTripPlanner() {
}
}
- // Build set of planned place IDs for unplanned filter
- const plannedIds = placesFilter === 'unplanned'
+ // Planned place IDs — needed by both the 'unplanned' filter (exclude them) and
+ // the new 'planned' filter (keep only them).
+ const plannedIds = placesFilter === 'unplanned' || placesFilter === 'planned'
? new Set(Object.values(assignments).flatMap(da => da.map(a => a.place?.id).filter(Boolean)))
: null
@@ -384,8 +385,12 @@ export function useTripPlanner() {
if (!placesCategoryFilter.has('uncategorized')) return false
} else if (!placesCategoryFilter.has(String(p.category_id))) return false
}
- if (hiddenPlaceIds.has(p.id)) return false
- if (plannedIds && plannedIds.has(p.id)) return false
+ // Collapsed-day declutter hides a day's stops on every filter EXCEPT 'planned':
+ // there the user asked to see the whole plan on the map, so a collapsed day
+ // must not drop its planned places.
+ if (placesFilter !== 'planned' && hiddenPlaceIds.has(p.id)) return false
+ if (placesFilter === 'unplanned' && plannedIds && plannedIds.has(p.id)) return false
+ if (placesFilter === 'planned' && plannedIds && !plannedIds.has(p.id)) return false
return true
})
}, [places, placesCategoryFilter, placesFilter, assignments, expandedDayIds])
diff --git a/shared/src/i18n/ar/places.ts b/shared/src/i18n/ar/places.ts
index 108a16728..d2380ebb3 100644
--- a/shared/src/i18n/ar/places.ts
+++ b/shared/src/i18n/ar/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'إلى أي يوم تريد الإضافة؟',
'places.all': 'الكل',
'places.unplanned': 'غير مخطط',
+ 'places.planned': 'مخطط لها',
'places.filterTracks': 'المسارات',
'places.sortByRating': 'الترتيب حسب التقييم',
'places.yourRating': 'تقييمك',
diff --git a/shared/src/i18n/br/places.ts b/shared/src/i18n/br/places.ts
index 829dc38ab..35c5fa411 100644
--- a/shared/src/i18n/br/places.ts
+++ b/shared/src/i18n/br/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Adicionar a qual dia?',
'places.all': 'Todos',
'places.unplanned': 'Não planejados',
+ 'places.planned': 'Planejados',
'places.filterTracks': 'Trilhas',
'places.sortByRating': 'Ordenar por avaliação',
'places.yourRating': 'Sua avaliação',
diff --git a/shared/src/i18n/ca/places.ts b/shared/src/i18n/ca/places.ts
index 81b9f42b2..b6076d731 100644
--- a/shared/src/i18n/ca/places.ts
+++ b/shared/src/i18n/ca/places.ts
@@ -40,6 +40,7 @@ const places: TranslationStrings = {
'places.assignToDay': "A quin dia l'afegeixo?",
'places.all': 'Tot',
'places.unplanned': 'Sense planificar',
+ 'places.planned': 'Planificats',
'places.filterTracks': 'Rutes',
'places.sortByRating': 'Ordena per valoració',
'places.yourRating': 'La teva valoració',
diff --git a/shared/src/i18n/cs/places.ts b/shared/src/i18n/cs/places.ts
index 633394d97..f9d3b658c 100644
--- a/shared/src/i18n/cs/places.ts
+++ b/shared/src/i18n/cs/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Přidat do kterého dne?',
'places.all': 'Vše',
'places.unplanned': 'Nezařazené',
+ 'places.planned': 'Naplánované',
'places.filterTracks': 'Trasy',
'places.sortByRating': 'Seřadit podle hodnocení',
'places.yourRating': 'Tvé hodnocení',
diff --git a/shared/src/i18n/de/places.ts b/shared/src/i18n/de/places.ts
index 53ec831e5..f291a3621 100644
--- a/shared/src/i18n/de/places.ts
+++ b/shared/src/i18n/de/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Zu welchem Tag hinzufügen?',
'places.all': 'Alle',
'places.unplanned': 'Ungeplant',
+ 'places.planned': 'Geplant',
'places.filterTracks': 'Tracks',
'places.sortByRating': 'Nach Bewertung sortieren',
'places.yourRating': 'Deine Bewertung',
diff --git a/shared/src/i18n/en/places.ts b/shared/src/i18n/en/places.ts
index aac098b37..314a2b85a 100644
--- a/shared/src/i18n/en/places.ts
+++ b/shared/src/i18n/en/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Add to which day?',
'places.all': 'All',
'places.unplanned': 'Unplanned',
+ 'places.planned': 'Planned',
'places.filterTracks': 'Tracks',
'places.sortByRating': 'Sort by rating',
'places.yourRating': 'Your rating',
diff --git a/shared/src/i18n/es/places.ts b/shared/src/i18n/es/places.ts
index 5ddbcc7f8..1a7040e63 100644
--- a/shared/src/i18n/es/places.ts
+++ b/shared/src/i18n/es/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': '¿A qué día añadirlo?',
'places.all': 'Todo',
'places.unplanned': 'Sin planificar',
+ 'places.planned': 'Planificados',
'places.filterTracks': 'Rutas',
'places.sortByRating': 'Ordenar por valoración',
'places.yourRating': 'Tu valoración',
diff --git a/shared/src/i18n/fr/places.ts b/shared/src/i18n/fr/places.ts
index 0ac58d8ef..38cd449b3 100644
--- a/shared/src/i18n/fr/places.ts
+++ b/shared/src/i18n/fr/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Ajouter à quel jour ?',
'places.all': 'Tous',
'places.unplanned': 'Non planifiés',
+ 'places.planned': 'Planifiés',
'places.filterTracks': 'Traces',
'places.sortByRating': 'Trier par note',
'places.yourRating': 'Ta note',
diff --git a/shared/src/i18n/gr/places.ts b/shared/src/i18n/gr/places.ts
index 8f330409f..c1f925da4 100644
--- a/shared/src/i18n/gr/places.ts
+++ b/shared/src/i18n/gr/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Σε ποια ημέρα να προστεθεί;',
'places.all': 'Όλα',
'places.unplanned': 'Μη προγραμματισμένα',
+ 'places.planned': 'Προγραμματισμένα',
'places.filterTracks': 'Ίχνη',
'places.sortByRating': 'Ταξινόμηση κατά βαθμολογία',
'places.yourRating': 'Η βαθμολογία σου',
diff --git a/shared/src/i18n/hu/places.ts b/shared/src/i18n/hu/places.ts
index 3123ddb3f..ac9da52eb 100644
--- a/shared/src/i18n/hu/places.ts
+++ b/shared/src/i18n/hu/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Melyik naphoz adod?',
'places.all': 'Összes',
'places.unplanned': 'Nem tervezett',
+ 'places.planned': 'Tervezett',
'places.filterTracks': 'Nyomvonalak',
'places.sortByRating': 'Rendezés értékelés szerint',
'places.yourRating': 'Az értékelésed',
diff --git a/shared/src/i18n/id/places.ts b/shared/src/i18n/id/places.ts
index dfc3e2cfc..ea04d1478 100644
--- a/shared/src/i18n/id/places.ts
+++ b/shared/src/i18n/id/places.ts
@@ -41,6 +41,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Tambah ke hari mana?',
'places.all': 'Semua',
'places.unplanned': 'Belum direncanakan',
+ 'places.planned': 'Direncanakan',
'places.filterTracks': 'Trek',
'places.sortByRating': 'Urutkan berdasarkan rating',
'places.yourRating': 'Rating kamu',
diff --git a/shared/src/i18n/it/places.ts b/shared/src/i18n/it/places.ts
index 7d965e7c6..21b5ccb69 100644
--- a/shared/src/i18n/it/places.ts
+++ b/shared/src/i18n/it/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'A quale giorno aggiungere?',
'places.all': 'Tutti',
'places.unplanned': 'Non pianificati',
+ 'places.planned': 'Pianificati',
'places.filterTracks': 'Tracce',
'places.sortByRating': 'Ordina per valutazione',
'places.yourRating': 'La tua valutazione',
diff --git a/shared/src/i18n/ja/places.ts b/shared/src/i18n/ja/places.ts
index 556f2b92a..68a24dbba 100644
--- a/shared/src/i18n/ja/places.ts
+++ b/shared/src/i18n/ja/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'どの日に追加しますか?',
'places.all': 'すべて',
'places.unplanned': '未計画',
+ 'places.planned': '計画済み',
'places.filterTracks': 'トラック',
'places.sortByRating': '評価順に並べ替え',
'places.yourRating': 'あなたの評価',
diff --git a/shared/src/i18n/ko/places.ts b/shared/src/i18n/ko/places.ts
index 3a78826c6..ddd780c49 100644
--- a/shared/src/i18n/ko/places.ts
+++ b/shared/src/i18n/ko/places.ts
@@ -41,6 +41,7 @@ const places: TranslationStrings = {
'places.assignToDay': '어느 날에 추가할까요?',
'places.all': '전체',
'places.unplanned': '미계획',
+ 'places.planned': '계획됨',
'places.filterTracks': '트랙',
'places.sortByRating': '평점순 정렬',
'places.yourRating': '내 평점',
diff --git a/shared/src/i18n/nl/places.ts b/shared/src/i18n/nl/places.ts
index 275aa1155..b212ae1d1 100644
--- a/shared/src/i18n/nl/places.ts
+++ b/shared/src/i18n/nl/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Aan welke dag toevoegen?',
'places.all': 'Alle',
'places.unplanned': 'Ongepland',
+ 'places.planned': 'Gepland',
'places.filterTracks': 'Tracks',
'places.sortByRating': 'Sorteren op beoordeling',
'places.yourRating': 'Jouw beoordeling',
diff --git a/shared/src/i18n/pl/places.ts b/shared/src/i18n/pl/places.ts
index 08d8a531b..7eec513eb 100644
--- a/shared/src/i18n/pl/places.ts
+++ b/shared/src/i18n/pl/places.ts
@@ -33,6 +33,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Do którego dnia dodać?',
'places.all': 'Wszystkie',
'places.unplanned': 'Niezaplanowane',
+ 'places.planned': 'Zaplanowane',
'places.filterTracks': 'Trasy',
'places.sortByRating': 'Sortuj według oceny',
'places.yourRating': 'Twoja ocena',
diff --git a/shared/src/i18n/ru/places.ts b/shared/src/i18n/ru/places.ts
index 5eae4926d..b5a4e7498 100644
--- a/shared/src/i18n/ru/places.ts
+++ b/shared/src/i18n/ru/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Добавить в какой день?',
'places.all': 'Все',
'places.unplanned': 'Незапланированные',
+ 'places.planned': 'Запланированные',
'places.filterTracks': 'Треки',
'places.sortByRating': 'Сортировать по рейтингу',
'places.yourRating': 'Твоя оценка',
diff --git a/shared/src/i18n/sv/places.ts b/shared/src/i18n/sv/places.ts
index 7573c11f7..e654a91a3 100644
--- a/shared/src/i18n/sv/places.ts
+++ b/shared/src/i18n/sv/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Lägg till vilken dag?',
'places.all': 'Alla',
'places.unplanned': 'Oplanerat',
+ 'places.planned': 'Planerat',
'places.filterTracks': 'Spår',
'places.sortByRating': 'Sortera efter betyg',
'places.yourRating': 'Ditt betyg',
diff --git a/shared/src/i18n/tr/places.ts b/shared/src/i18n/tr/places.ts
index ef7e20ae4..d9dd5e92b 100644
--- a/shared/src/i18n/tr/places.ts
+++ b/shared/src/i18n/tr/places.ts
@@ -44,6 +44,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Hangi güne eklensin?',
'places.all': 'Tüm',
'places.unplanned': 'Planlanmamış',
+ 'places.planned': 'Planlanmış',
'places.filterTracks': 'Parçalar',
'places.sortByRating': 'Puana göre sırala',
'places.yourRating': 'Senin puanın',
diff --git a/shared/src/i18n/uk/places.ts b/shared/src/i18n/uk/places.ts
index 73c776180..8b5b523db 100644
--- a/shared/src/i18n/uk/places.ts
+++ b/shared/src/i18n/uk/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Додати на який день?',
'places.all': 'Усі',
'places.unplanned': 'Незаплановані',
+ 'places.planned': 'Заплановані',
'places.filterTracks': 'Треки',
'places.sortByRating': 'Сортувати за рейтингом',
'places.yourRating': 'Твоя оцінка',
diff --git a/shared/src/i18n/vi/places.ts b/shared/src/i18n/vi/places.ts
index 78ba11fd2..629a15ce7 100644
--- a/shared/src/i18n/vi/places.ts
+++ b/shared/src/i18n/vi/places.ts
@@ -42,6 +42,7 @@ const places: TranslationStrings = {
'places.assignToDay': 'Thêm vào ngày nào?',
'places.all': 'Tất cả',
'places.unplanned': 'Không có kế hoạch',
+ 'places.planned': 'Có kế hoạch',
'places.filterTracks': 'Bài hát',
'places.sortByRating': 'Sắp xếp theo đánh giá',
'places.yourRating': 'Đánh giá của bạn',
diff --git a/shared/src/i18n/zh-TW/places.ts b/shared/src/i18n/zh-TW/places.ts
index ccad0b5f1..5c17d395a 100644
--- a/shared/src/i18n/zh-TW/places.ts
+++ b/shared/src/i18n/zh-TW/places.ts
@@ -41,6 +41,7 @@ const places: TranslationStrings = {
'places.assignToDay': '新增到哪一天?',
'places.all': '全部',
'places.unplanned': '未規劃',
+ 'places.planned': '已規劃',
'places.filterTracks': '路線',
'places.sortByRating': '依評分排序',
'places.yourRating': '你的評分',
diff --git a/shared/src/i18n/zh/places.ts b/shared/src/i18n/zh/places.ts
index 76e21bab4..b12907025 100644
--- a/shared/src/i18n/zh/places.ts
+++ b/shared/src/i18n/zh/places.ts
@@ -41,6 +41,7 @@ const places: TranslationStrings = {
'places.assignToDay': '添加到哪一天?',
'places.all': '全部',
'places.unplanned': '未规划',
+ 'places.planned': '已规划',
'places.filterTracks': '路线',
'places.sortByRating': '按评分排序',
'places.yourRating': '你的评分',