feat(reservations): desktop bookings and transports in the phone's look

The Bookings and Transports tabs on the desktop take the phone's card
language: a tinted status band, the type chip and framed fields. One bar
holds the search, a filter popover for status, types and travelers, the
view switch and the view options.

Three views over the same filtered entries: cards (four per row at most),
a dense list grouped by day, and a timeline with a trip scale and a day
scale by the hour. A booking opens as a dialog with everything it holds,
the booking code blurred by the existing setting, and "On map".

Work in progress: only en and de are translated, and tests, help guides
and the wiki still follow.
This commit is contained in:
Maurice
2026-09-27 00:34:32 +02:00
parent 237f42a493
commit acd0d6511e
17 changed files with 2709 additions and 955 deletions
+52
View File
@@ -182,5 +182,57 @@ const reservations: TranslationStrings = {
'reservations.travelers.label': 'Reisende',
'reservations.travelers.assign': 'Reisende zuweisen',
'reservations.travelers.none': 'Noch keine Reisenden im Trip.',
'reservations.status.switchTo': 'Auf {status} setzen',
'reservations.view.label': 'Ansicht',
'reservations.view.cards': 'Karten',
'reservations.view.list': 'Liste',
'reservations.view.timeline': 'Zeitleiste',
'reservations.filter': 'Filtern',
'reservations.searchPlaceholder': 'Suchen',
'reservations.results': '{shown} von {total}',
'reservations.resetFilters': 'Filter zurücksetzen',
'reservations.noMatches': 'Nichts passt zu diesen Filtern',
'reservations.viewOptions': 'Ansicht anpassen',
'reservations.resetView': 'Ansicht zurücksetzen',
'reservations.group.label': 'Gruppieren nach',
'reservations.group.status': 'Status',
'reservations.group.day': 'Tag',
'reservations.group.type': 'Typ',
'reservations.group.none': 'Nicht gruppieren',
'reservations.group.before': 'Vor der Reise',
'reservations.group.after': 'Nach der Reise',
'reservations.group.undated': 'Ohne Datum',
'reservations.sort.label': 'Sortieren nach',
'reservations.sort.date': 'Datum',
'reservations.sort.title': 'Titel',
'reservations.sort.type': 'Typ',
'reservations.sort.status': 'Status',
'reservations.sort.earlyFirst': 'Früheste zuerst',
'reservations.sort.lateFirst': 'Späteste zuerst',
'reservations.sort.aToZ': 'A bis Z',
'reservations.sort.zToA': 'Z bis A',
'reservations.timeline.dayCount': '{count} Tage',
'reservations.timeline.zoom': 'Zoom',
'reservations.timeline.trip': 'Reise',
'reservations.timeline.day': 'Tag',
'reservations.timeline.prevDay': 'Vorheriger Tag',
'reservations.timeline.nextDay': 'Nächster Tag',
'reservations.timeline.openDay': '{day} nach Stunden öffnen',
'reservations.timeline.nothingThisDay': 'An diesem Tag steht nichts an.',
'reservations.timeline.today': 'Heute',
'reservations.timeline.now': 'jetzt',
'reservations.timeline.byType': 'Eine Spur pro Typ',
'reservations.timeline.context': 'Anderen Tab einblenden',
'reservations.timeline.contextStays': 'Unterkünfte',
'reservations.timeline.contextTransports': 'Transporte',
'reservations.timeline.noneDated': 'Hier hat noch nichts ein Datum.',
'reservations.undated': 'Ohne Datum',
'reservations.nights': 'Nächte',
'reservations.start': 'Beginn',
'reservations.end': 'Ende',
'reservations.rename': 'Umbenennen',
'reservations.copyCode': 'Buchungscode kopieren',
'reservations.copyFailed': 'Kopieren hat nicht geklappt',
'reservations.showInFiles': 'In Dateien zeigen',
};
export default reservations;
+1
View File
@@ -6,5 +6,6 @@ const transport: TranslationStrings = {
'transport.modalTitle.edit': 'Transport bearbeiten',
'transport.title': 'Transporte',
'transport.addManual': 'Transport',
'transport.empty': 'Noch keine Transporte',
};
export default transport;
+52
View File
@@ -181,5 +181,57 @@ const reservations: TranslationStrings = {
'reservations.travelers.label': 'Travelers',
'reservations.travelers.assign': 'Assign travelers',
'reservations.travelers.none': 'No trip members yet.',
'reservations.status.switchTo': 'Set to {status}',
'reservations.view.label': 'View',
'reservations.view.cards': 'Cards',
'reservations.view.list': 'List',
'reservations.view.timeline': 'Timeline',
'reservations.filter': 'Filter',
'reservations.searchPlaceholder': 'Search',
'reservations.results': '{shown} of {total}',
'reservations.resetFilters': 'Reset filters',
'reservations.noMatches': 'Nothing matches these filters',
'reservations.viewOptions': 'View options',
'reservations.resetView': 'Reset view',
'reservations.group.label': 'Group by',
'reservations.group.status': 'Status',
'reservations.group.day': 'Day',
'reservations.group.type': 'Type',
'reservations.group.none': 'No grouping',
'reservations.group.before': 'Before the trip',
'reservations.group.after': 'After the trip',
'reservations.group.undated': 'No date',
'reservations.sort.label': 'Sort by',
'reservations.sort.date': 'Date',
'reservations.sort.title': 'Title',
'reservations.sort.type': 'Type',
'reservations.sort.status': 'Status',
'reservations.sort.earlyFirst': 'Earliest first',
'reservations.sort.lateFirst': 'Latest first',
'reservations.sort.aToZ': 'A to Z',
'reservations.sort.zToA': 'Z to A',
'reservations.timeline.dayCount': '{count} days',
'reservations.timeline.zoom': 'Zoom',
'reservations.timeline.trip': 'Trip',
'reservations.timeline.day': 'Day',
'reservations.timeline.prevDay': 'Previous day',
'reservations.timeline.nextDay': 'Next day',
'reservations.timeline.openDay': 'Open {day} by the hour',
'reservations.timeline.nothingThisDay': 'Nothing on this day.',
'reservations.timeline.today': 'Today',
'reservations.timeline.now': 'now',
'reservations.timeline.byType': 'One lane per type',
'reservations.timeline.context': 'Show the other tab',
'reservations.timeline.contextStays': 'Stays',
'reservations.timeline.contextTransports': 'Transports',
'reservations.timeline.noneDated': 'None of these has a date yet.',
'reservations.undated': 'No date',
'reservations.nights': 'Nights',
'reservations.start': 'Start',
'reservations.end': 'End',
'reservations.rename': 'Rename',
'reservations.copyCode': 'Copy booking code',
'reservations.copyFailed': 'Could not copy',
'reservations.showInFiles': 'Show in files',
};
export default reservations;
+1
View File
@@ -6,5 +6,6 @@ const transport: TranslationStrings = {
'transport.modalTitle.edit': 'Edit transport',
'transport.title': 'Transports',
'transport.addManual': 'Transport',
'transport.empty': 'No transports yet',
};
export default transport;