feat(budget): add "Fuel" and "Parking" expense categories

- Adds two new fixed budget categories: fuel ("Fuel") and parkings
  ("Parking"), alongside the existing set (Accommodation, Food & drink,
  Groceries, Transport, Flights, Activities, Sightseeing, Shopping,
  Fees & tickets, Health, Tips, Other).
- Icon/color metadata added for both (Fuel and ParkingCircle from
  lucide-react), plus legacy free-text aliases (gas/petrol->fuel,
  parking->parkings) for existing/imported expense rows.
- Label strings added for all 23 supported locales.
- Adds test coverage for the new categories and legacy alias mapping.
This commit is contained in:
MikeDabrowski
2026-08-08 22:43:19 +02:00
committed by Maurice
parent 875f87b885
commit 999236f944
27 changed files with 95 additions and 1 deletions
+8
View File
@@ -3,6 +3,7 @@ import {
budgetUpdateMembersRequestSchema,
budgetToggleMemberPaidRequestSchema,
budgetReorderItemsRequestSchema,
COST_CATEGORIES,
} from './budget.schema';
import { describe, it, expect } from 'vitest';
@@ -41,3 +42,10 @@ describe('budgetReorderItemsRequestSchema', () => {
expect(budgetReorderItemsRequestSchema.safeParse({ orderedIds: ['a'] }).success).toBe(false);
});
});
describe('COST_CATEGORIES', () => {
it('includes fuel and parkings alongside the existing fixed categories', () => {
expect(COST_CATEGORIES).toContain('fuel');
expect(COST_CATEGORIES).toContain('parkings');
});
});
+2
View File
@@ -46,6 +46,8 @@ export const COST_CATEGORIES = [
'fees',
'health',
'tips',
'fuel',
'parkings',
'other',
] as const;
export type CostCategory = (typeof COST_CATEGORIES)[number];
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'الرسوم والتذاكر',
'costs.cat.health': 'الصحة',
'costs.cat.tips': 'البقشيش',
'costs.cat.fuel': 'وقود',
'costs.cat.parkings': 'موقف سيارات',
'costs.cat.other': 'أخرى',
'costs.daysCount': '{count} أيام',
'costs.travelers': '{count} مسافرين',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Taxas e ingressos',
'costs.cat.health': 'Saúde',
'costs.cat.tips': 'Gorjetas',
'costs.cat.fuel': 'Combustível',
'costs.cat.parkings': 'Estacionamento',
'costs.cat.other': 'Outros',
'costs.daysCount': '{count} dias',
'costs.travelers': '{count} viajantes',
+2
View File
@@ -116,6 +116,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Taxes i entrades',
'costs.cat.health': 'Salut',
'costs.cat.tips': 'Propines',
'costs.cat.fuel': 'Combustible',
'costs.cat.parkings': 'Aparcament',
'costs.cat.other': 'Altres',
'costs.daysCount': '{count} dies',
'costs.travelers': '{count} viatgers',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Poplatky a vstupenky',
'costs.cat.health': 'Zdraví',
'costs.cat.tips': 'Spropitné',
'costs.cat.fuel': 'Palivo',
'costs.cat.parkings': 'Parkování',
'costs.cat.other': 'Ostatní',
'costs.daysCount': '{count} dní',
'costs.travelers': '{count} cestovatelů',
+2
View File
@@ -120,6 +120,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Gebühren & Tickets',
'costs.cat.health': 'Gesundheit',
'costs.cat.tips': 'Trinkgeld',
'costs.cat.fuel': 'Kraftstoff',
'costs.cat.parkings': 'Parken',
'costs.cat.other': 'Sonstiges',
'costs.daysCount': '{count} Tage',
'costs.travelers': '{count} Reisende',
+2
View File
@@ -124,6 +124,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Fees & tickets',
'costs.cat.health': 'Health',
'costs.cat.tips': 'Tips',
'costs.cat.fuel': 'Fuel',
'costs.cat.parkings': 'Parking',
'costs.cat.other': 'Other',
'costs.daysCount': '{count} days',
'costs.travelers': '{count} travelers',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Tasas y entradas',
'costs.cat.health': 'Salud',
'costs.cat.tips': 'Propinas',
'costs.cat.fuel': 'Combustible',
'costs.cat.parkings': 'Aparcamiento',
'costs.cat.other': 'Otros',
'costs.daysCount': '{count} días',
'costs.travelers': '{count} viajeros',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Frais et billets',
'costs.cat.health': 'Santé',
'costs.cat.tips': 'Pourboires',
'costs.cat.fuel': 'Carburant',
'costs.cat.parkings': 'Parking',
'costs.cat.other': 'Autre',
'costs.daysCount': '{count} jours',
'costs.travelers': '{count} voyageurs',
+2
View File
@@ -118,6 +118,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Τέλη & εισιτήρια',
'costs.cat.health': 'Υγεία',
'costs.cat.tips': 'Φιλοδωρήματα',
'costs.cat.fuel': 'Καύσιμα',
'costs.cat.parkings': 'Στάθμευση',
'costs.cat.other': 'Άλλα',
'costs.daysCount': '{count} ημέρες',
'costs.travelers': '{count} ταξιδιώτες',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Díjak és jegyek',
'costs.cat.health': 'Egészség',
'costs.cat.tips': 'Borravaló',
'costs.cat.fuel': 'Üzemanyag',
'costs.cat.parkings': 'Parkolás',
'costs.cat.other': 'Egyéb',
'costs.daysCount': '{count} nap',
'costs.travelers': '{count} utazó',
+2
View File
@@ -117,6 +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.other': 'Lainnya',
'costs.daysCount': '{count} hari',
'costs.travelers': '{count} pelancong',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Tariffe e biglietti',
'costs.cat.health': 'Salute',
'costs.cat.tips': 'Mance',
'costs.cat.fuel': 'Carburante',
'costs.cat.parkings': 'Parcheggio',
'costs.cat.other': 'Altro',
'costs.daysCount': '{count} giorni',
'costs.travelers': '{count} viaggiatori',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': '手数料・チケット',
'costs.cat.health': '健康',
'costs.cat.tips': 'チップ',
'costs.cat.fuel': '燃料',
'costs.cat.parkings': '駐車場',
'costs.cat.other': 'その他',
'costs.daysCount': '{count}日間',
'costs.travelers': '{count}人の旅行者',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': '요금 및 입장권',
'costs.cat.health': '건강',
'costs.cat.tips': '팁',
'costs.cat.fuel': '연료',
'costs.cat.parkings': '주차',
'costs.cat.other': '기타',
'costs.daysCount': '{count}일',
'costs.travelers': '여행자 {count}명',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Kosten & tickets',
'costs.cat.health': 'Gezondheid',
'costs.cat.tips': 'Fooien',
'costs.cat.fuel': 'Brandstof',
'costs.cat.parkings': 'Parkeren',
'costs.cat.other': 'Overig',
'costs.daysCount': '{count} dagen',
'costs.travelers': '{count} reizigers',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Opłaty i bilety',
'costs.cat.health': 'Zdrowie',
'costs.cat.tips': 'Napiwki',
'costs.cat.fuel': 'Paliwo',
'costs.cat.parkings': 'Parking',
'costs.cat.other': 'Inne',
'costs.daysCount': 'Dni: {count}',
'costs.travelers': 'Podróżnych: {count}',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Сборы и билеты',
'costs.cat.health': 'Здоровье',
'costs.cat.tips': 'Чаевые',
'costs.cat.fuel': 'Топливо',
'costs.cat.parkings': 'Парковка',
'costs.cat.other': 'Прочее',
'costs.daysCount': '{count} дней',
'costs.travelers': '{count} путешественников',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Avgifter och biljetter',
'costs.cat.health': 'Hälsa',
'costs.cat.tips': 'Dricks',
'costs.cat.fuel': 'Bränsle',
'costs.cat.parkings': 'Parkering',
'costs.cat.other': 'Annat',
'costs.daysCount': '{count} dagar',
'costs.travelers': '{count} resenärer',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Ücretler & biletler',
'costs.cat.health': 'Sağlık',
'costs.cat.tips': 'Bahşişler',
'costs.cat.fuel': 'Yakıt',
'costs.cat.parkings': 'Otopark',
'costs.cat.other': 'Diğer',
'costs.daysCount': '{count} gün',
'costs.travelers': '{count} yolcu',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Збори та квитки',
'costs.cat.health': 'Здоров’я',
'costs.cat.tips': 'Чайові',
'costs.cat.fuel': 'Пальне',
'costs.cat.parkings': 'Паркування',
'costs.cat.other': 'Інше',
'costs.daysCount': '{count} днів',
'costs.travelers': '{count} мандрівників',
+2
View File
@@ -117,6 +117,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': 'Phí & vé',
'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.other': 'Khác',
'costs.daysCount': '{count} ngày',
'costs.travelers': '{count} người',
+2
View File
@@ -116,6 +116,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': '費用與票券',
'costs.cat.health': '健康',
'costs.cat.tips': '小費',
'costs.cat.fuel': '燃油',
'costs.cat.parkings': '停車',
'costs.cat.other': '其他',
'costs.daysCount': '{count} 天',
'costs.travelers': '{count} 位旅伴',
+2
View File
@@ -116,6 +116,8 @@ const budget: TranslationStrings = {
'costs.cat.fees': '费用与门票',
'costs.cat.health': '健康',
'costs.cat.tips': '小费',
'costs.cat.fuel': '燃油',
'costs.cat.parkings': '停车',
'costs.cat.other': '其他',
'costs.daysCount': '{count} 天',
'costs.travelers': '{count} 位同行者',