From 942e1932c90f0db907686dcdc2e88ec71e2b985e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maurice=20B=C3=B6e?= Date: Fri, 21 Aug 2026 14:14:23 +0200 Subject: [PATCH] fix(budget): name the category parking and file parking bookings in it The key was 'parkings', which is not a word and does not match the 'parking' the reservation type uses everywhere else. The shared trip page prints the stored category verbatim, so a share link would have shown "parkings" in every language. The category also had no relationship to the booking type of the same name: RESERVATION_TYPE_TO_COST_CATEGORY still sent a parking booking's auto-expense to Transport, so the new bucket sat empty next to the costs that belong in it while a manually typed "parking" resolved into it. Both paths agree now. --- .../components/Budget/costsCategories.test.ts | 16 +++++++++++----- client/src/components/Budget/costsCategories.tsx | 4 ++-- shared/src/budget/budget.schema.spec.ts | 16 ++++++++++++++-- shared/src/budget/budget.schema.ts | 4 ++-- shared/src/i18n/ar/budget.ts | 2 +- shared/src/i18n/br/budget.ts | 2 +- shared/src/i18n/ca/budget.ts | 2 +- shared/src/i18n/cs/budget.ts | 2 +- shared/src/i18n/de/budget.ts | 2 +- shared/src/i18n/en/budget.ts | 2 +- shared/src/i18n/es/budget.ts | 2 +- shared/src/i18n/fr/budget.ts | 2 +- shared/src/i18n/gr/budget.ts | 2 +- shared/src/i18n/hu/budget.ts | 2 +- shared/src/i18n/id/budget.ts | 4 ++-- shared/src/i18n/it/budget.ts | 2 +- shared/src/i18n/ja/budget.ts | 2 +- shared/src/i18n/ko/budget.ts | 2 +- shared/src/i18n/nl/budget.ts | 2 +- shared/src/i18n/pl/budget.ts | 2 +- shared/src/i18n/ru/budget.ts | 2 +- shared/src/i18n/sv/budget.ts | 2 +- shared/src/i18n/tr/budget.ts | 2 +- shared/src/i18n/uk/budget.ts | 2 +- shared/src/i18n/vi/budget.ts | 2 +- shared/src/i18n/zh-TW/budget.ts | 2 +- shared/src/i18n/zh/budget.ts | 2 +- 27 files changed, 53 insertions(+), 35 deletions(-) diff --git a/client/src/components/Budget/costsCategories.test.ts b/client/src/components/Budget/costsCategories.test.ts index d316d6430..d4a48918b 100644 --- a/client/src/components/Budget/costsCategories.test.ts +++ b/client/src/components/Budget/costsCategories.test.ts @@ -1,9 +1,9 @@ import { describe, it, expect } from 'vitest' -import { COST_CATEGORIES } from '@trek/shared' +import { COST_CATEGORIES, typeToCostCategory } from '@trek/shared' import { COST_CAT_META, COST_CATEGORY_LIST, catMeta } from './costsCategories' describe('COST_CAT_META', () => { - it('has metadata for every fixed category, including fuel and parkings', () => { + it('has metadata for every fixed category, including fuel and parking', () => { for (const key of COST_CATEGORIES) { expect(COST_CAT_META[key]).toBeDefined() expect(COST_CAT_META[key].key).toBe(key) @@ -16,15 +16,21 @@ describe('COST_CAT_META', () => { }) describe('catMeta', () => { - it('resolves fuel and parkings directly', () => { + it('resolves fuel and parking directly', () => { expect(catMeta('fuel').key).toBe('fuel') - expect(catMeta('parkings').key).toBe('parkings') + expect(catMeta('parking').key).toBe('parking') }) it('maps legacy/free-text aliases to the new categories', () => { expect(catMeta('gas').key).toBe('fuel') expect(catMeta('petrol').key).toBe('fuel') - expect(catMeta('parking').key).toBe('parkings') + expect(catMeta('Parking').key).toBe('parking') + expect(catMeta('car park').key).toBe('parking') + }) + + it('resolves a parking booking the same way whichever path created the expense', () => { + expect(catMeta(typeToCostCategory('parking')).key).toBe('parking') + expect(catMeta('parking').key).toBe(typeToCostCategory('parking')) }) it('falls back to other for unknown categories', () => { diff --git a/client/src/components/Budget/costsCategories.tsx b/client/src/components/Budget/costsCategories.tsx index be1502e0b..16c49bd39 100644 --- a/client/src/components/Budget/costsCategories.tsx +++ b/client/src/components/Budget/costsCategories.tsx @@ -28,7 +28,7 @@ export const COST_CAT_META: Record = { health: { key: 'health', labelKey: 'costs.cat.health', Icon: HeartPulse, color: '#dc2626' }, tips: { key: 'tips', labelKey: 'costs.cat.tips', Icon: Coins, color: '#d97706' }, fuel: { key: 'fuel', labelKey: 'costs.cat.fuel', Icon: Fuel, color: '#f59e0b' }, - parkings: { key: 'parkings', labelKey: 'costs.cat.parkings', Icon: ParkingCircle, color: '#3b82f6' }, + parking: { key: 'parking', labelKey: 'costs.cat.parking', Icon: ParkingCircle, color: '#3b82f6' }, other: { key: 'other', labelKey: 'costs.cat.other', Icon: MoreHorizontal, color: '#6b7280' }, } @@ -54,7 +54,7 @@ const LEGACY_CATEGORY_MAP: Record = { health: 'health', medical: 'health', tip: 'tips', tips: 'tips', gas: 'fuel', fuel: 'fuel', petrol: 'fuel', - parking: 'parkings', parkings: 'parkings', + parking: 'parking', parkings: 'parking', 'car park': 'parking', other: 'other', misc: 'other', } diff --git a/shared/src/budget/budget.schema.spec.ts b/shared/src/budget/budget.schema.spec.ts index aa2b9efc8..86642bbc8 100644 --- a/shared/src/budget/budget.schema.spec.ts +++ b/shared/src/budget/budget.schema.spec.ts @@ -4,6 +4,7 @@ import { budgetToggleMemberPaidRequestSchema, budgetReorderItemsRequestSchema, COST_CATEGORIES, + typeToCostCategory, } from './budget.schema'; import { describe, it, expect } from 'vitest'; @@ -44,8 +45,19 @@ describe('budgetReorderItemsRequestSchema', () => { }); describe('COST_CATEGORIES', () => { - it('includes fuel and parkings alongside the existing fixed categories', () => { + it('includes fuel and parking alongside the existing fixed categories', () => { expect(COST_CATEGORIES).toContain('fuel'); - expect(COST_CATEGORIES).toContain('parkings'); + expect(COST_CATEGORIES).toContain('parking'); + }); +}); + +describe('typeToCostCategory', () => { + it('files a parking booking under parking, not transport', () => { + expect(typeToCostCategory('parking')).toBe('parking'); + }); + + it('leaves the other vehicle types on transport', () => { + expect(typeToCostCategory('car-rental')).toBe('transport'); + expect(typeToCostCategory('taxi')).toBe('transport'); }); }); diff --git a/shared/src/budget/budget.schema.ts b/shared/src/budget/budget.schema.ts index d3f0490fe..cf137b705 100644 --- a/shared/src/budget/budget.schema.ts +++ b/shared/src/budget/budget.schema.ts @@ -47,7 +47,7 @@ export const COST_CATEGORIES = [ 'health', 'tips', 'fuel', - 'parkings', + 'parking', 'other', ] as const; export type CostCategory = (typeof COST_CATEGORIES)[number]; @@ -72,7 +72,7 @@ const RESERVATION_TYPE_TO_COST_CATEGORY: Record = { hotel: 'accommodation', accommodation: 'accommodation', lodging: 'accommodation', - parking: 'transport', + parking: 'parking', restaurant: 'food', activity: 'activities', }; diff --git a/shared/src/i18n/ar/budget.ts b/shared/src/i18n/ar/budget.ts index b0756d897..a4257dd90 100644 --- a/shared/src/i18n/ar/budget.ts +++ b/shared/src/i18n/ar/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'الصحة', 'costs.cat.tips': 'البقشيش', 'costs.cat.fuel': 'وقود', - 'costs.cat.parkings': 'موقف سيارات', + 'costs.cat.parking': 'موقف سيارات', 'costs.cat.other': 'أخرى', 'costs.daysCount': '{count} أيام', 'costs.travelers': '{count} مسافرين', diff --git a/shared/src/i18n/br/budget.ts b/shared/src/i18n/br/budget.ts index f8b0b94e6..4bbdd272e 100644 --- a/shared/src/i18n/br/budget.ts +++ b/shared/src/i18n/br/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Saúde', 'costs.cat.tips': 'Gorjetas', 'costs.cat.fuel': 'Combustível', - 'costs.cat.parkings': 'Estacionamento', + 'costs.cat.parking': 'Estacionamento', 'costs.cat.other': 'Outros', 'costs.daysCount': '{count} dias', 'costs.travelers': '{count} viajantes', diff --git a/shared/src/i18n/ca/budget.ts b/shared/src/i18n/ca/budget.ts index 53cd10bc0..aea51944b 100644 --- a/shared/src/i18n/ca/budget.ts +++ b/shared/src/i18n/ca/budget.ts @@ -117,7 +117,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Salut', 'costs.cat.tips': 'Propines', 'costs.cat.fuel': 'Combustible', - 'costs.cat.parkings': 'Aparcament', + 'costs.cat.parking': 'Aparcament', 'costs.cat.other': 'Altres', 'costs.daysCount': '{count} dies', 'costs.travelers': '{count} viatgers', diff --git a/shared/src/i18n/cs/budget.ts b/shared/src/i18n/cs/budget.ts index 8e994a267..74bb31ff1 100644 --- a/shared/src/i18n/cs/budget.ts +++ b/shared/src/i18n/cs/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Zdraví', 'costs.cat.tips': 'Spropitné', 'costs.cat.fuel': 'Palivo', - 'costs.cat.parkings': 'Parkování', + 'costs.cat.parking': 'Parkování', 'costs.cat.other': 'Ostatní', 'costs.daysCount': '{count} dní', 'costs.travelers': '{count} cestovatelů', diff --git a/shared/src/i18n/de/budget.ts b/shared/src/i18n/de/budget.ts index 70ceb7fee..90f25eed1 100644 --- a/shared/src/i18n/de/budget.ts +++ b/shared/src/i18n/de/budget.ts @@ -121,7 +121,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Gesundheit', 'costs.cat.tips': 'Trinkgeld', 'costs.cat.fuel': 'Kraftstoff', - 'costs.cat.parkings': 'Parken', + 'costs.cat.parking': 'Parken', 'costs.cat.other': 'Sonstiges', 'costs.daysCount': '{count} Tage', 'costs.travelers': '{count} Reisende', diff --git a/shared/src/i18n/en/budget.ts b/shared/src/i18n/en/budget.ts index 6e3d6103a..58d246684 100644 --- a/shared/src/i18n/en/budget.ts +++ b/shared/src/i18n/en/budget.ts @@ -125,7 +125,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Health', 'costs.cat.tips': 'Tips', 'costs.cat.fuel': 'Fuel', - 'costs.cat.parkings': 'Parking', + 'costs.cat.parking': 'Parking', 'costs.cat.other': 'Other', 'costs.daysCount': '{count} days', 'costs.travelers': '{count} travelers', diff --git a/shared/src/i18n/es/budget.ts b/shared/src/i18n/es/budget.ts index fd536e435..bb33fafca 100644 --- a/shared/src/i18n/es/budget.ts +++ b/shared/src/i18n/es/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Salud', 'costs.cat.tips': 'Propinas', 'costs.cat.fuel': 'Combustible', - 'costs.cat.parkings': 'Aparcamiento', + 'costs.cat.parking': 'Aparcamiento', 'costs.cat.other': 'Otros', 'costs.daysCount': '{count} días', 'costs.travelers': '{count} viajeros', diff --git a/shared/src/i18n/fr/budget.ts b/shared/src/i18n/fr/budget.ts index 83b6b6183..969967bbd 100644 --- a/shared/src/i18n/fr/budget.ts +++ b/shared/src/i18n/fr/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Santé', 'costs.cat.tips': 'Pourboires', 'costs.cat.fuel': 'Carburant', - 'costs.cat.parkings': 'Parking', + 'costs.cat.parking': 'Parking', 'costs.cat.other': 'Autre', 'costs.daysCount': '{count} jours', 'costs.travelers': '{count} voyageurs', diff --git a/shared/src/i18n/gr/budget.ts b/shared/src/i18n/gr/budget.ts index 7615d3c77..752248330 100644 --- a/shared/src/i18n/gr/budget.ts +++ b/shared/src/i18n/gr/budget.ts @@ -119,7 +119,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Υγεία', 'costs.cat.tips': 'Φιλοδωρήματα', 'costs.cat.fuel': 'Καύσιμα', - 'costs.cat.parkings': 'Στάθμευση', + 'costs.cat.parking': 'Στάθμευση', 'costs.cat.other': 'Άλλα', 'costs.daysCount': '{count} ημέρες', 'costs.travelers': '{count} ταξιδιώτες', diff --git a/shared/src/i18n/hu/budget.ts b/shared/src/i18n/hu/budget.ts index 269526ca1..806263ad1 100644 --- a/shared/src/i18n/hu/budget.ts +++ b/shared/src/i18n/hu/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Egészség', 'costs.cat.tips': 'Borravaló', 'costs.cat.fuel': 'Üzemanyag', - 'costs.cat.parkings': 'Parkolás', + 'costs.cat.parking': 'Parkolás', 'costs.cat.other': 'Egyéb', 'costs.daysCount': '{count} nap', 'costs.travelers': '{count} utazó', diff --git a/shared/src/i18n/id/budget.ts b/shared/src/i18n/id/budget.ts index 02d540616..559751f92 100644 --- a/shared/src/i18n/id/budget.ts +++ b/shared/src/i18n/id/budget.ts @@ -117,8 +117,8 @@ const budget: TranslationStrings = { 'costs.cat.fees': 'Biaya & tiket', 'costs.cat.health': 'Kesehatan', 'costs.cat.tips': 'Tip', - 'costs.cat.fuel': 'Bahan Bakar', - 'costs.cat.parkings': 'Parkir', + 'costs.cat.fuel': 'Bahan bakar', + 'costs.cat.parking': 'Parkir', 'costs.cat.other': 'Lainnya', 'costs.daysCount': '{count} hari', 'costs.travelers': '{count} pelancong', diff --git a/shared/src/i18n/it/budget.ts b/shared/src/i18n/it/budget.ts index 0a9b18866..942fdb770 100644 --- a/shared/src/i18n/it/budget.ts +++ b/shared/src/i18n/it/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Salute', 'costs.cat.tips': 'Mance', 'costs.cat.fuel': 'Carburante', - 'costs.cat.parkings': 'Parcheggio', + 'costs.cat.parking': 'Parcheggio', 'costs.cat.other': 'Altro', 'costs.daysCount': '{count} giorni', 'costs.travelers': '{count} viaggiatori', diff --git a/shared/src/i18n/ja/budget.ts b/shared/src/i18n/ja/budget.ts index 9f8ccc68d..33c09e352 100644 --- a/shared/src/i18n/ja/budget.ts +++ b/shared/src/i18n/ja/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': '健康', 'costs.cat.tips': 'チップ', 'costs.cat.fuel': '燃料', - 'costs.cat.parkings': '駐車場', + 'costs.cat.parking': '駐車場', 'costs.cat.other': 'その他', 'costs.daysCount': '{count}日間', 'costs.travelers': '{count}人の旅行者', diff --git a/shared/src/i18n/ko/budget.ts b/shared/src/i18n/ko/budget.ts index 5d27a63f6..645aa2730 100644 --- a/shared/src/i18n/ko/budget.ts +++ b/shared/src/i18n/ko/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': '건강', 'costs.cat.tips': '팁', 'costs.cat.fuel': '연료', - 'costs.cat.parkings': '주차', + 'costs.cat.parking': '주차', 'costs.cat.other': '기타', 'costs.daysCount': '{count}일', 'costs.travelers': '여행자 {count}명', diff --git a/shared/src/i18n/nl/budget.ts b/shared/src/i18n/nl/budget.ts index 3ab904121..c59ca439c 100644 --- a/shared/src/i18n/nl/budget.ts +++ b/shared/src/i18n/nl/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Gezondheid', 'costs.cat.tips': 'Fooien', 'costs.cat.fuel': 'Brandstof', - 'costs.cat.parkings': 'Parkeren', + 'costs.cat.parking': 'Parkeren', 'costs.cat.other': 'Overig', 'costs.daysCount': '{count} dagen', 'costs.travelers': '{count} reizigers', diff --git a/shared/src/i18n/pl/budget.ts b/shared/src/i18n/pl/budget.ts index 0f128bc21..a51660faa 100644 --- a/shared/src/i18n/pl/budget.ts +++ b/shared/src/i18n/pl/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Zdrowie', 'costs.cat.tips': 'Napiwki', 'costs.cat.fuel': 'Paliwo', - 'costs.cat.parkings': 'Parking', + 'costs.cat.parking': 'Parking', 'costs.cat.other': 'Inne', 'costs.daysCount': 'Dni: {count}', 'costs.travelers': 'Podróżnych: {count}', diff --git a/shared/src/i18n/ru/budget.ts b/shared/src/i18n/ru/budget.ts index 8136ab245..767193e78 100644 --- a/shared/src/i18n/ru/budget.ts +++ b/shared/src/i18n/ru/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Здоровье', 'costs.cat.tips': 'Чаевые', 'costs.cat.fuel': 'Топливо', - 'costs.cat.parkings': 'Парковка', + 'costs.cat.parking': 'Парковка', 'costs.cat.other': 'Прочее', 'costs.daysCount': '{count} дней', 'costs.travelers': '{count} путешественников', diff --git a/shared/src/i18n/sv/budget.ts b/shared/src/i18n/sv/budget.ts index a0378a774..6e0851587 100644 --- a/shared/src/i18n/sv/budget.ts +++ b/shared/src/i18n/sv/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Hälsa', 'costs.cat.tips': 'Dricks', 'costs.cat.fuel': 'Bränsle', - 'costs.cat.parkings': 'Parkering', + 'costs.cat.parking': 'Parkering', 'costs.cat.other': 'Annat', 'costs.daysCount': '{count} dagar', 'costs.travelers': '{count} resenärer', diff --git a/shared/src/i18n/tr/budget.ts b/shared/src/i18n/tr/budget.ts index 93a67006c..2d9573f31 100644 --- a/shared/src/i18n/tr/budget.ts +++ b/shared/src/i18n/tr/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Sağlık', 'costs.cat.tips': 'Bahşişler', 'costs.cat.fuel': 'Yakıt', - 'costs.cat.parkings': 'Otopark', + 'costs.cat.parking': 'Otopark', 'costs.cat.other': 'Diğer', 'costs.daysCount': '{count} gün', 'costs.travelers': '{count} yolcu', diff --git a/shared/src/i18n/uk/budget.ts b/shared/src/i18n/uk/budget.ts index cd583f96c..ddda112fe 100644 --- a/shared/src/i18n/uk/budget.ts +++ b/shared/src/i18n/uk/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Здоров’я', 'costs.cat.tips': 'Чайові', 'costs.cat.fuel': 'Пальне', - 'costs.cat.parkings': 'Паркування', + 'costs.cat.parking': 'Паркування', 'costs.cat.other': 'Інше', 'costs.daysCount': '{count} днів', 'costs.travelers': '{count} мандрівників', diff --git a/shared/src/i18n/vi/budget.ts b/shared/src/i18n/vi/budget.ts index 1e4c57a88..8f4f7b06f 100644 --- a/shared/src/i18n/vi/budget.ts +++ b/shared/src/i18n/vi/budget.ts @@ -118,7 +118,7 @@ const budget: TranslationStrings = { 'costs.cat.health': 'Sức khỏe', 'costs.cat.tips': 'Mẹo', 'costs.cat.fuel': 'Nhiên liệu', - 'costs.cat.parkings': 'Bãi đỗ xe', + 'costs.cat.parking': 'Bãi đỗ xe', 'costs.cat.other': 'Khác', 'costs.daysCount': '{count} ngày', 'costs.travelers': '{count} người', diff --git a/shared/src/i18n/zh-TW/budget.ts b/shared/src/i18n/zh-TW/budget.ts index a6af98f62..a865a62d5 100644 --- a/shared/src/i18n/zh-TW/budget.ts +++ b/shared/src/i18n/zh-TW/budget.ts @@ -117,7 +117,7 @@ const budget: TranslationStrings = { 'costs.cat.health': '健康', 'costs.cat.tips': '小費', 'costs.cat.fuel': '燃油', - 'costs.cat.parkings': '停車', + 'costs.cat.parking': '停車', 'costs.cat.other': '其他', 'costs.daysCount': '{count} 天', 'costs.travelers': '{count} 位旅伴', diff --git a/shared/src/i18n/zh/budget.ts b/shared/src/i18n/zh/budget.ts index 96ad4ff55..4faa0a7f6 100644 --- a/shared/src/i18n/zh/budget.ts +++ b/shared/src/i18n/zh/budget.ts @@ -117,7 +117,7 @@ const budget: TranslationStrings = { 'costs.cat.health': '健康', 'costs.cat.tips': '小费', 'costs.cat.fuel': '燃油', - 'costs.cat.parkings': '停车', + 'costs.cat.parking': '停车', 'costs.cat.other': '其他', 'costs.daysCount': '{count} 天', 'costs.travelers': '{count} 位同行者',