feat(categories): icons for parking, bus stops, stations, airports and fuel (#2706)

The category picker had no icon to tell a car park or a terminal apart from the
places a trip visits. Five transport icons join the shared table, which the admin
pickers, map pins and the PDF all read; the ship's tooltip now also says ferry.
This commit is contained in:
Maurice
2026-11-13 09:18:50 +01:00
parent e7bff6681e
commit 66d85729ff
3 changed files with 34 additions and 2 deletions
@@ -0,0 +1,29 @@
import { describe, expect, it } from 'vitest';
import { CATEGORY_ICON_MAP, ICON_LABELS, getCategoryIcon } from './categoryIcons';
import { BusFront, Fuel, MapPin, ParkingSquare, PlaneTakeoff, TrainFront } from 'lucide-react';
describe('categoryIcons', () => {
it('FE-COMP-CATICONS-001: every icon the category picker offers has a label for its tooltip', () => {
expect(Object.keys(CATEGORY_ICON_MAP).filter((name) => !ICON_LABELS[name])).toEqual([]);
expect(Object.keys(ICON_LABELS).filter((name) => !CATEGORY_ICON_MAP[name])).toEqual([]);
});
it('FE-COMP-CATICONS-002: parking, stops, stations, airports and fuel have icons of their own (#2706)', () => {
expect(getCategoryIcon('ParkingSquare')).toBe(ParkingSquare);
expect(getCategoryIcon('BusFront')).toBe(BusFront);
expect(getCategoryIcon('TrainFront')).toBe(TrainFront);
expect(getCategoryIcon('PlaneTakeoff')).toBe(PlaneTakeoff);
expect(getCategoryIcon('Fuel')).toBe(Fuel);
expect(ICON_LABELS.ParkingSquare).toBe('Parking');
expect(ICON_LABELS.PlaneTakeoff).toBe('Airport');
expect(ICON_LABELS.Ship).toBe('Ship / Ferry');
});
it('FE-COMP-CATICONS-003: an unknown or missing icon name falls back to the pin', () => {
expect(getCategoryIcon('NoSuchIcon')).toBe(MapPin);
expect(getCategoryIcon(null)).toBe(MapPin);
expect(getCategoryIcon(undefined)).toBe(MapPin);
});
});
@@ -1,6 +1,7 @@
import {
MapPin, Building2, BedDouble, UtensilsCrossed, Landmark, ShoppingBag,
Bus, Train, Car, Plane, Ship, Bike,
BusFront, TrainFront, PlaneTakeoff, ParkingSquare, Fuel,
Activity, Dumbbell, Mountain, Tent, Anchor,
Coffee, Beer, Wine, Utensils,
Camera, Music, Theater, Ticket,
@@ -15,6 +16,7 @@ import {
export const CATEGORY_ICON_MAP: Record<string, LucideIcon> = {
MapPin, Building2, BedDouble, UtensilsCrossed, Landmark, ShoppingBag,
Bus, Train, Car, Plane, Ship, Bike,
BusFront, TrainFront, PlaneTakeoff, ParkingSquare, Fuel,
Activity, Dumbbell, Mountain, Tent, Anchor,
Coffee, Beer, Wine, Utensils,
Camera, Music, Theater, Ticket,
@@ -28,7 +30,8 @@ export const CATEGORY_ICON_MAP: Record<string, LucideIcon> = {
export const ICON_LABELS: Record<string, string> = {
MapPin: 'Pin', Building2: 'Building', BedDouble: 'Hotel', UtensilsCrossed: 'Restaurant',
Landmark: 'Attraction', ShoppingBag: 'Shopping', Bus: 'Bus', Train: 'Train',
Car: 'Car', Plane: 'Plane', Ship: 'Ship', Bike: 'Bicycle',
Car: 'Car', Plane: 'Plane', Ship: 'Ship / Ferry', Bike: 'Bicycle',
BusFront: 'Bus stop', TrainFront: 'Station', PlaneTakeoff: 'Airport', ParkingSquare: 'Parking', Fuel: 'Fuel',
Activity: 'Activity', Dumbbell: 'Fitness', Mountain: 'Mountain', Tent: 'Camping',
Anchor: 'Harbor', Coffee: 'Cafe', Beer: 'Bar', Wine: 'Wine', Utensils: 'Food',
Camera: 'Photo', Music: 'Music', Theater: 'Theater', Ticket: 'Events',
+1 -1
View File
@@ -18,7 +18,7 @@ A category is a label consisting of a name, a color, and an icon. Users assign c
Click **New Category** (top right of the card). A dialog opens:
1. **Category name**: required. Type it into the dialog's head; **Enter** saves.
2. **Icon**: a grid of 47 curated Lucide icons (Pin, Hotel, Restaurant, Transport, Nature and so on). Click an icon to select it. The default icon is `MapPin`.
2. **Icon**: a grid of 54 curated Lucide icons (Pin, Hotel, Restaurant, Bus stop, Station, Airport, Parking, Nature and so on). Click an icon to select it. The default icon is `MapPin`.
3. **Color**: 12 preset swatches plus **Choose custom color** (pipette button). The default color is `#6366f1` (indigo). The 12 presets are:
`#6366f1`, `#8b5cf6`, `#ec4899`, `#ef4444`, `#f97316`, `#f59e0b`, `#10b981`, `#06b6d4`, `#3b82f6`, `#84cc16`, `#6b7280`, `#1f2937`