mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
refactor(planner): share the transport detail day and segment labels between desktop and phone
The transport detail dialog and the phone transport sheet name the booking's day and each segment's own booking code through transportDetailModel, next to the files filter they already share. The rest of the two views reads the booking differently on purpose and stays as it is.
This commit is contained in:
@@ -12,6 +12,7 @@ import { parseReservationMetadata } from '../../utils/flightLegs'
|
||||
import { BookingDialogHeader } from './bookings/BookingDialogShell'
|
||||
import { BOX, Eyebrow, Field, fs, toneColor, toneOf } from './bookings/bookingParts'
|
||||
import { filesFor } from '../../utils/reservationFiles'
|
||||
import { bookingDayLabel, segmentCodeLabel } from './transportDetailModel'
|
||||
import { TransitLegs, transitSummary } from './bookings/transitParts'
|
||||
import type { Reservation } from '../../types'
|
||||
|
||||
@@ -185,8 +186,7 @@ function detailCells(res: Reservation, meta: Record<string, unknown>, t: Transla
|
||||
if (legs.length > 1) {
|
||||
for (const leg of legs) {
|
||||
if (!leg?.confirmation_number) continue
|
||||
const segment = [leg.from, leg.to].filter(Boolean).join(' → ')
|
||||
add(segment || t('reservations.confirmationCode'), leg.confirmation_number, true)
|
||||
add(segmentCodeLabel(leg, t), leg.confirmation_number, true)
|
||||
}
|
||||
}
|
||||
return cells
|
||||
@@ -196,9 +196,7 @@ function detailCells(res: Reservation, meta: Record<string, unknown>, t: Transla
|
||||
function whenOf(res: Reservation, locale: string, timeFormat: string): { day: string; time: string } {
|
||||
const { date, time } = splitReservationDateTime(res.reservation_time)
|
||||
const { time: endTime } = splitReservationDateTime(res.reservation_end_time)
|
||||
const day = date
|
||||
? new Date(date + 'T00:00:00Z').toLocaleDateString(locale, { weekday: 'short', day: 'numeric', month: 'short', timeZone: 'UTC' })
|
||||
: ''
|
||||
const day = date ? bookingDayLabel(date, locale) : ''
|
||||
const start = time ? formatTime(time, locale, timeFormat) : ''
|
||||
const end = endTime ? formatTime(endTime, locale, timeFormat) : ''
|
||||
return { day, time: start && end ? `${start} → ${end}` : start }
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// FE-PLANNER-TRANSPORTDETAIL-001 to -002: the labels the desktop transport detail
|
||||
// and the phone transport sheet both read off a booking.
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { bookingDayLabel, segmentCodeLabel } from './transportDetailModel';
|
||||
|
||||
const t = (key: string) => `t:${key}`;
|
||||
|
||||
describe('transportDetailModel', () => {
|
||||
it('FE-PLANNER-TRANSPORTDETAIL-001: the day reads as weekday, day and month, on the calendar date itself', () => {
|
||||
expect(bookingDayLabel('2026-07-01', 'en-US')).toBe('Wed, Jul 1');
|
||||
expect(bookingDayLabel('2026-12-31', 'en-US')).toBe('Thu, Dec 31');
|
||||
});
|
||||
|
||||
it('FE-PLANNER-TRANSPORTDETAIL-002: a segment code is listed under its route, or the plain code label', () => {
|
||||
expect(segmentCodeLabel({ from: 'MUC', to: 'FRA' }, t)).toBe('MUC → FRA');
|
||||
expect(segmentCodeLabel({ from: 'MUC', to: null }, t)).toBe('MUC');
|
||||
expect(segmentCodeLabel({ to: 'FRA' }, t)).toBe('FRA');
|
||||
expect(segmentCodeLabel({ from: null, to: '' }, t)).toBe('t:reservations.confirmationCode');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
type Translate = (key: string, params?: Record<string, string | number>) => string;
|
||||
|
||||
/**
|
||||
* What the desktop transport detail dialog and the phone transport sheet both read
|
||||
* off a booking. The booking's files come from utils/reservationFiles.
|
||||
*/
|
||||
|
||||
/** The day a booking runs on, as the head of either detail names it, in the locale's order ("Wed, Jul 1" in en-US). */
|
||||
export function bookingDayLabel(date: string, locale: string): string {
|
||||
return new Date(`${date}T00:00:00Z`).toLocaleDateString(locale, {
|
||||
weekday: 'short',
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The name a segment's own booking code is listed under (#1943): where it leaves
|
||||
* from and where it goes, or the plain booking code label when the segment names
|
||||
* neither.
|
||||
*/
|
||||
export function segmentCodeLabel(leg: { from?: string | null; to?: string | null }, t: Translate): string {
|
||||
return [leg.from, leg.to].filter(Boolean).join(' → ') || t('reservations.confirmationCode');
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import { getFlightLegs, getTrainLegs, usesStationRoute } from '../../../../utils
|
||||
import { openFile } from '../../../../utils/fileDownload'
|
||||
import { runsOnDay } from '../../../../utils/reservationRoutes'
|
||||
import { filesFor } from '../../../../utils/reservationFiles'
|
||||
import { bookingDayLabel, segmentCodeLabel } from '../../../../components/Planner/transportDetailModel'
|
||||
import type { Reservation } from '../../../../types'
|
||||
import { Eyebrow, INNER_CLS, StatBox, TileHeader, displayTime } from './MTripSheetUi'
|
||||
|
||||
@@ -88,11 +89,7 @@ export default function MTransportSheet({ planner, shell }: MTripSheetsProps) {
|
||||
if (meta.flight_number) subParts.push(meta.flight_number)
|
||||
if (meta.train_number) subParts.push(meta.train_number)
|
||||
if (from?.name && to?.name) subParts.push(`${from.name} → ${to.name}`)
|
||||
else if (date) {
|
||||
subParts.push(new Date(`${date}T00:00:00Z`).toLocaleDateString(locale, {
|
||||
weekday: 'short', day: 'numeric', month: 'short', timeZone: 'UTC',
|
||||
}))
|
||||
}
|
||||
else if (date) subParts.push(bookingDayLabel(date, locale))
|
||||
|
||||
const seat = meta.seat
|
||||
const platform = meta.platform
|
||||
@@ -247,7 +244,7 @@ export default function MTransportSheet({ planner, shell }: MTripSheetsProps) {
|
||||
{legCodes.map((leg, i) => (
|
||||
<div key={i} className="flex items-center gap-2">
|
||||
<span className="min-w-0 flex-1 truncate text-[0.71875rem] font-medium">
|
||||
{[leg.from, leg.to].filter(Boolean).join(' → ') || t('reservations.confirmationCode')}
|
||||
{segmentCodeLabel(leg, t)}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
Reference in New Issue
Block a user