diff --git a/client/src/components/Roadtrip/RoadtripCorridorPanel.tsx b/client/src/components/Roadtrip/RoadtripCorridorPanel.tsx index ef6236c50..4761fb68f 100644 --- a/client/src/components/Roadtrip/RoadtripCorridorPanel.tsx +++ b/client/src/components/Roadtrip/RoadtripCorridorPanel.tsx @@ -1,7 +1,6 @@ import React from 'react' import { - Fuel, Zap, ParkingSquare, Tent, Utensils, Camera, Search, Plus, RotateCw, - AlertTriangle, MapPin, X, type LucideIcon, + Search, Plus, RotateCw, AlertTriangle, X, BedDouble, MapPin, } from 'lucide-react' import { useTranslation } from '../../i18n/TranslationContext' import { Tooltip } from '../shared/Tooltip' @@ -90,18 +89,26 @@ function ResultRow({ poi, onAdd }: { poi: CorridorPoi; onAdd?: () => void }): Re {/* Always there, quiet until the row is under the pointer: a button that only exists on hover is one a keyboard user has to find by faith. */} - {onAdd ? ( - - - - ) : null} + {onAdd ? (() => { + // One button, two meanings. Somewhere to sleep ends the day rather than + // interrupting the drive, so the icon and the label say that before the dialog + // opens instead of after. + const night = poi.category === 'hotel' + const label = night ? t('roadtrip.stay.nightAction') : t('roadtrip.poi.add') + const Icon = night ? BedDouble : Plus + return ( + + + + ) + })() : null} ) } diff --git a/client/src/components/Roadtrip/RoadtripSidebar.tsx b/client/src/components/Roadtrip/RoadtripSidebar.tsx index 8610c8659..84adc3f51 100644 --- a/client/src/components/Roadtrip/RoadtripSidebar.tsx +++ b/client/src/components/Roadtrip/RoadtripSidebar.tsx @@ -576,7 +576,7 @@ function Arrival({ entry }: { entry: ScheduleEntry }): React.ReactElement { ) } -function Stop({ stop, number, entry, late, driveFindings, selected, continues, onSelect, onMove, canMove, onEditStay }: { +function Stop({ stop, number, entry, late, driveFindings, selected, continues, starts, onSelect, onMove, canMove, onEditStay }: { stop: RoadtripStop /** Position within the day — the same count the map badges its markers with. */ number: number @@ -587,6 +587,8 @@ function Stop({ stop, number, entry, late, driveFindings, selected, continues, o selected: boolean /** Whether the chain goes on below, so the marker keeps hold of the line. */ continues: boolean + /** First row of the day: no line above it, because the chain starts here. */ + starts?: boolean onSelect?: () => void /** Moves this stop by one place. Absent means the chain is read-only. */ onMove?: (delta: number) => void @@ -614,16 +616,20 @@ function Stop({ stop, number, entry, late, driveFindings, selected, continues, o className="group grid w-full rounded-lg text-start focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent" style={RAIL_GRID} > - {/* The marker and the line below it share one column, so the chain runs unbroken - from stop to stop rather than restarting under whatever the row happens to hold. */} + {/* The marker sits level with the middle of the row rather than at its top, the + way the corridor list already places its own badges: a number pinned to the + first line drifts away from the row as soon as a stop carries a stay and a walk + under its name. The line grows above and below it, so the chain still runs + unbroken from stop to stop. */} + {starts ? null : } {number} - {continues ? : null} + {continues ? : null} {/* The fill stops at the rail: the number is part of the chain, not part of the row @@ -810,6 +816,7 @@ function DaySection({ day, selectedAssignmentId, onSelectStop, onReorderStop, on driveFindings={day.driveWarnings.filter(w => w.index === i)} selected={selectedAssignmentId === stop.assignmentId} continues={i < last} + starts={i === 0} onSelect={onSelectStop ? () => onSelectStop(stop.placeId, stop.assignmentId) : undefined} onMove={onReorderStop ? delta => onReorderStop(day.dayId, stop.assignmentId, i + delta) : undefined} canMove={{ up: i > 0, down: i < last }} diff --git a/client/src/components/Roadtrip/roadtripModel.test.ts b/client/src/components/Roadtrip/roadtripModel.test.ts index 1e8ad75dc..3f33ff957 100644 --- a/client/src/components/Roadtrip/roadtripModel.test.ts +++ b/client/src/components/Roadtrip/roadtripModel.test.ts @@ -289,14 +289,28 @@ describe('deriveDriveWarnings', () => { { legMinutes: null, dayMinutes: null, rangeKm: 100 }, 0, ) - // 21.5 + 103.4 on arrival at HEM, then 244.7 on arrival at Berlin, because the budget - // starts over after each finding. + // 21.5 + 103.4 on arrival at HEM, and then it keeps counting, because nothing on this + // trip fills up. expect(out.warnings).toEqual([ { index: 2, code: 'range', sinceKm: 125 }, - { index: 3, code: 'range', sinceKm: 245 }, + { index: 3, code: 'range', sinceKm: 370 }, ]) }) + it('FE-ROADTRIP-MODEL-070: arriving at a petrol station is the plan, not a warning', () => { + // Same trip, but HEM is marked as fuel. Reaching it with an empty tank is exactly + // what it is there for, so nothing is flagged on it; the budget still starts over, + // and the next stretch is measured from there. + const out = deriveDriveWarnings( + [leg(20, 21.5), leg(62, 103.4), leg(155, 244.7)], + [false, false, true, false], + { legMinutes: null, dayMinutes: null, rangeKm: 100 }, + 0, + ) + expect(out.warnings).toEqual([{ index: 3, code: 'range', sinceKm: 245 }]) + // 245 and not 370: HEM filled the tank, so Berlin counts from there. + }) + const noLimits = { legMinutes: null, dayMinutes: null, rangeKm: null } const leg = (minutes: number, km: number) => ({ duration: minutes * 60, distance: km * 1000 }) @@ -329,20 +343,34 @@ describe('deriveDriveWarnings', () => { expect(out.day).toEqual({ code: 'dayDriving', minutes: 400, limitMinutes: 360 }) }) - it('FE-ROADTRIP-MODEL-063: the range runs out once and then starts over', () => { - // Without the reset, a 1800 km trip on a 600 km range flags every leg after the first - // overrun, which is a column of red nobody reads. With it the marks stand one range - // apart and each means "fill up around here". + it('FE-ROADTRIP-MODEL-063: the figure keeps counting until something actually refuels', () => { + // A warning is not a fill-up. Zeroing the budget at one made every figure after the + // first wrong: the second stop would claim a fresh tank while the same one is still + // in the car. const out = deriveDriveWarnings( [leg(60, 300), leg(60, 400), leg(60, 300), leg(60, 400)], [false, false, false, false, false], { ...noLimits, rangeKm: 600 }, 0, ) - expect(out.warnings.map(w => w.code)).toEqual(['range', 'range']) - // 300 + 400 on arrival at stop 2, which is exactly what adding up the two drive bands - // above it gives. - expect(out.warnings[0]).toEqual({ index: 2, code: 'range', sinceKm: 700 }) + expect(out.warnings).toEqual([ + { index: 2, code: 'range', sinceKm: 700 }, + { index: 3, code: 'range', sinceKm: 1000 }, + { index: 4, code: 'range', sinceKm: 1400 }, + ]) + }) + + it('FE-ROADTRIP-MODEL-071: adding a fuel stop is what stops the run of warnings', () => { + // The same drive with a charger at stop 2. Nothing is flagged there, because reaching + // it on an empty tank is what it is for; everything after counts from zero again, so + // the three-warning run above collapses to one. + const out = deriveDriveWarnings( + [leg(60, 300), leg(60, 400), leg(60, 300), leg(60, 400)], + [false, false, true, false, false], + { ...noLimits, rangeKm: 600 }, + 0, + ) + expect(out.warnings).toEqual([{ index: 4, code: 'range', sinceKm: 700 }]) }) it('FE-ROADTRIP-MODEL-064: filling up starts the budget over, resting does not', () => { diff --git a/client/src/components/Roadtrip/roadtripModel.ts b/client/src/components/Roadtrip/roadtripModel.ts index 49dd79c5a..9b8ec45e8 100644 --- a/client/src/components/Roadtrip/roadtripModel.ts +++ b/client/src/components/Roadtrip/roadtripModel.ts @@ -304,10 +304,13 @@ export function sumLegSeconds(legSeconds: (number | undefined)[]): number { * an hour of the day would simply never fire. All three limits are therefore durations and * kilometres, which exist as soon as a leg has routed. * - * The range budget carries across midnight, because a tank does not empty overnight, and - * resets to zero after a finding: without that reset, one trip of 1800 km on a 600 km - * range flags every leg after the first overrun, which is a column of red nobody reads. - * With it, the marks stand one range apart and each one means "fill up around here". + * The range budget resets at a fuel or charging stop and NOWHERE ELSE. It carries across + * midnight, because a tank does not empty overnight, and it keeps counting past a finding, + * because a warning is not a fill-up. Zeroing it there made the second figure wrong and + * every one after it: a day reading 245 km at one stop and 121 at the next claims the 121 + * is a fresh tank, when it is 366 on the same one. A run of warnings down a stretch with + * no fuel on it is not noise; it is the answer, and it stops the moment a fuel or + * charging stop is put in. * * An unrouted leg gives the budget up entirely rather than guessing, the same way the * schedule abandons its cursor: a distance we do not have cannot be added to one we do. @@ -341,9 +344,12 @@ export function deriveDriveWarnings( budget = null } else if (budget !== null) { budget += metres / 1000 - if (limits.rangeKm && budget > limits.rangeKm) { + // Not on a stop that fills up: arriving at a petrol station with an empty tank is + // the plan working, not a problem, and a warning there would sit on the one stop + // that answers it. No reset either — a warning is not a fill-up, and the figure has + // to keep counting until a fuel or charging stop actually puts one in. + if (limits.rangeKm && budget > limits.rangeKm && !refuelsAt[at]) { warnings.push({ index: at, code: 'range', sinceKm: Math.round(budget) }) - budget = 0 } } } diff --git a/shared/src/i18n/ar/roadtrip.ts b/shared/src/i18n/ar/roadtrip.ts index cbd7e92ed..0b4535992 100644 --- a/shared/src/i18n/ar/roadtrip.ts +++ b/shared/src/i18n/ar/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'غير محددة', 'roadtrip.stop.none': 'وجهة', 'roadtrip.stop.kindHelp': 'التوقف في الطريق يُرسم على المسار ولا يُحتسب ضمن عدد التوقفات.', + 'roadtrip.stay.mode.pause': 'استراحة', + 'roadtrip.stay.mode.night': 'مبيت', + 'roadtrip.stay.checkOutDay': 'المغادرة في', + 'roadtrip.stay.dayNumber': 'اليوم {number}', + 'roadtrip.stay.nightAdded': 'أُضيف كمبيت', + 'roadtrip.stay.nightAction': 'إضافة كمبيت', 'roadtrip.poi.rest': 'استراحة', 'roadtrip.poi.campsite': 'مخيم', 'roadtrip.poi.food': 'طعام', diff --git a/shared/src/i18n/br/roadtrip.ts b/shared/src/i18n/br/roadtrip.ts index b2cb362d8..f9048e136 100644 --- a/shared/src/i18n/br/roadtrip.ts +++ b/shared/src/i18n/br/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Nenhum definido', 'roadtrip.stop.none': 'Um destino', 'roadtrip.stop.kindHelp': 'Uma parada no caminho é desenhada no trajeto e não é contada.', + 'roadtrip.stay.mode.pause': 'Pausa', + 'roadtrip.stay.mode.night': 'Pernoite', + 'roadtrip.stay.checkOutDay': 'Saída em', + 'roadtrip.stay.dayNumber': 'Dia {number}', + 'roadtrip.stay.nightAdded': 'Adicionado como pernoite', + 'roadtrip.stay.nightAction': 'Adicionar como pernoite', 'roadtrip.poi.rest': 'Área de descanso', 'roadtrip.poi.campsite': 'Camping', 'roadtrip.poi.food': 'Comida', diff --git a/shared/src/i18n/ca/roadtrip.ts b/shared/src/i18n/ca/roadtrip.ts index 7fca4f9f7..0cb15311a 100644 --- a/shared/src/i18n/ca/roadtrip.ts +++ b/shared/src/i18n/ca/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Cap definit', 'roadtrip.stop.none': 'Una destinació', 'roadtrip.stop.kindHelp': 'Una parada al camí es dibuixa sobre el trajecte i no es compta.', + 'roadtrip.stay.mode.pause': 'Parada', + 'roadtrip.stay.mode.night': 'Pernoctar', + 'roadtrip.stay.checkOutDay': 'Sortida el', + 'roadtrip.stay.dayNumber': 'Dia {number}', + 'roadtrip.stay.nightAdded': 'Afegit com a pernoctació', + 'roadtrip.stay.nightAction': 'Afegeix com a pernoctació', 'roadtrip.poi.rest': 'Àrea de descans', 'roadtrip.poi.campsite': 'Càmping', 'roadtrip.poi.food': 'Menjar', diff --git a/shared/src/i18n/cs/roadtrip.ts b/shared/src/i18n/cs/roadtrip.ts index 9dd5acfc8..5d65b343e 100644 --- a/shared/src/i18n/cs/roadtrip.ts +++ b/shared/src/i18n/cs/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Nenastaveno', 'roadtrip.stop.none': 'Cíl cesty', 'roadtrip.stop.kindHelp': 'Zastávka po cestě se kreslí na trase a nepočítá se.', + 'roadtrip.stay.mode.pause': 'Pauza', + 'roadtrip.stay.mode.night': 'Nocleh', + 'roadtrip.stay.checkOutDay': 'Odjezd', + 'roadtrip.stay.dayNumber': 'Den {number}', + 'roadtrip.stay.nightAdded': 'Přidáno jako nocleh', + 'roadtrip.stay.nightAction': 'Přidat jako nocleh', 'roadtrip.poi.rest': 'Odpočívadlo', 'roadtrip.poi.campsite': 'Kemp', 'roadtrip.poi.food': 'Jídlo', diff --git a/shared/src/i18n/de/roadtrip.ts b/shared/src/i18n/de/roadtrip.ts index 7f57b1981..eaa85f6f7 100644 --- a/shared/src/i18n/de/roadtrip.ts +++ b/shared/src/i18n/de/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Keine gesetzt', 'roadtrip.stop.none': 'Ein Ziel', 'roadtrip.stop.kindHelp': 'Ein Halt unterwegs wird auf der Fahrt gezeichnet und nicht mitgezählt.', + 'roadtrip.stay.mode.pause': 'Pause', + 'roadtrip.stay.mode.night': 'Übernachten', + 'roadtrip.stay.checkOutDay': 'Abreise am', + 'roadtrip.stay.dayNumber': 'Tag {number}', + 'roadtrip.stay.nightAdded': 'Als Übernachtung hinzugefügt', + 'roadtrip.stay.nightAction': 'Als Übernachtung hinzufügen', 'roadtrip.poi.rest': 'Rastplatz', 'roadtrip.poi.campsite': 'Campingplatz', 'roadtrip.poi.food': 'Essen', diff --git a/shared/src/i18n/en/roadtrip.ts b/shared/src/i18n/en/roadtrip.ts index 0d7c40a2d..4e4c18ffb 100644 --- a/shared/src/i18n/en/roadtrip.ts +++ b/shared/src/i18n/en/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'None set', 'roadtrip.stop.none': 'A destination', 'roadtrip.stop.kindHelp': 'A pause on the way is drawn on the drive and left out of the stop count.', + 'roadtrip.stay.mode.pause': 'Pause', + 'roadtrip.stay.mode.night': 'Overnight', + 'roadtrip.stay.checkOutDay': 'Check out on', + 'roadtrip.stay.dayNumber': 'Day {number}', + 'roadtrip.stay.nightAdded': 'Added as an overnight stay', + 'roadtrip.stay.nightAction': 'Add as an overnight stay', 'roadtrip.poi.rest': 'Rest area', 'roadtrip.poi.campsite': 'Campsite', 'roadtrip.poi.food': 'Food', diff --git a/shared/src/i18n/es/roadtrip.ts b/shared/src/i18n/es/roadtrip.ts index e83107ce9..3d767f934 100644 --- a/shared/src/i18n/es/roadtrip.ts +++ b/shared/src/i18n/es/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Ninguno definido', 'roadtrip.stop.none': 'Un destino', 'roadtrip.stop.kindHelp': 'Una parada en el camino se dibuja sobre el trayecto y no se cuenta.', + 'roadtrip.stay.mode.pause': 'Parada', + 'roadtrip.stay.mode.night': 'Pernoctar', + 'roadtrip.stay.checkOutDay': 'Salida el', + 'roadtrip.stay.dayNumber': 'Día {number}', + 'roadtrip.stay.nightAdded': 'Añadido como pernoctación', + 'roadtrip.stay.nightAction': 'Añadir como pernoctación', 'roadtrip.poi.rest': 'Área de descanso', 'roadtrip.poi.campsite': 'Camping', 'roadtrip.poi.food': 'Comida', diff --git a/shared/src/i18n/fr/roadtrip.ts b/shared/src/i18n/fr/roadtrip.ts index aeebbfff9..a76d8eacc 100644 --- a/shared/src/i18n/fr/roadtrip.ts +++ b/shared/src/i18n/fr/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Aucune définie', 'roadtrip.stop.none': 'Une destination', 'roadtrip.stop.kindHelp': 'Un arrêt en chemin est dessiné sur le trajet et n’est pas compté.', + 'roadtrip.stay.mode.pause': 'Pause', + 'roadtrip.stay.mode.night': 'Nuitée', + 'roadtrip.stay.checkOutDay': 'Départ le', + 'roadtrip.stay.dayNumber': 'Jour {number}', + 'roadtrip.stay.nightAdded': 'Ajouté comme nuitée', + 'roadtrip.stay.nightAction': 'Ajouter comme nuitée', 'roadtrip.poi.rest': 'Aire de repos', 'roadtrip.poi.campsite': 'Camping', 'roadtrip.poi.food': 'Restauration', diff --git a/shared/src/i18n/gr/roadtrip.ts b/shared/src/i18n/gr/roadtrip.ts index 1c452e27e..b3338f053 100644 --- a/shared/src/i18n/gr/roadtrip.ts +++ b/shared/src/i18n/gr/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Δεν έχουν οριστεί', 'roadtrip.stop.none': 'Προορισμός', 'roadtrip.stop.kindHelp': 'Μια στάση στον δρόμο σχεδιάζεται πάνω στη διαδρομή και δεν προσμετράται.', + 'roadtrip.stay.mode.pause': 'Στάση', + 'roadtrip.stay.mode.night': 'Διανυκτέρευση', + 'roadtrip.stay.checkOutDay': 'Αναχώρηση', + 'roadtrip.stay.dayNumber': 'Ημέρα {number}', + 'roadtrip.stay.nightAdded': 'Προστέθηκε ως διανυκτέρευση', + 'roadtrip.stay.nightAction': 'Προσθήκη ως διανυκτέρευση', 'roadtrip.poi.rest': 'Χώρος ανάπαυσης', 'roadtrip.poi.campsite': 'Κάμπινγκ', 'roadtrip.poi.food': 'Φαγητό', diff --git a/shared/src/i18n/hu/roadtrip.ts b/shared/src/i18n/hu/roadtrip.ts index e3666f45b..6594941d6 100644 --- a/shared/src/i18n/hu/roadtrip.ts +++ b/shared/src/i18n/hu/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Nincs beállítva', 'roadtrip.stop.none': 'Úti cél', 'roadtrip.stop.kindHelp': 'Az útközbeni megálló az útvonalra kerül, és nem számít bele.', + 'roadtrip.stay.mode.pause': 'Szünet', + 'roadtrip.stay.mode.night': 'Éjszakázás', + 'roadtrip.stay.checkOutDay': 'Kijelentkezés', + 'roadtrip.stay.dayNumber': '{number}. nap', + 'roadtrip.stay.nightAdded': 'Hozzáadva éjszakázásként', + 'roadtrip.stay.nightAction': 'Hozzáadás éjszakázásként', 'roadtrip.poi.rest': 'Pihenőhely', 'roadtrip.poi.campsite': 'Kemping', 'roadtrip.poi.food': 'Étkezés', diff --git a/shared/src/i18n/id/roadtrip.ts b/shared/src/i18n/id/roadtrip.ts index c87edc901..c76908285 100644 --- a/shared/src/i18n/id/roadtrip.ts +++ b/shared/src/i18n/id/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Belum diatur', 'roadtrip.stop.none': 'Sebuah tujuan', 'roadtrip.stop.kindHelp': 'Perhentian di jalan digambar pada rute dan tidak dihitung.', + 'roadtrip.stay.mode.pause': 'Istirahat', + 'roadtrip.stay.mode.night': 'Menginap', + 'roadtrip.stay.checkOutDay': 'Check out', + 'roadtrip.stay.dayNumber': 'Hari {number}', + 'roadtrip.stay.nightAdded': 'Ditambahkan sebagai menginap', + 'roadtrip.stay.nightAction': 'Tambahkan sebagai menginap', 'roadtrip.poi.rest': 'Tempat istirahat', 'roadtrip.poi.campsite': 'Perkemahan', 'roadtrip.poi.food': 'Makanan', diff --git a/shared/src/i18n/it/roadtrip.ts b/shared/src/i18n/it/roadtrip.ts index bd42c75ee..5c6ebbbda 100644 --- a/shared/src/i18n/it/roadtrip.ts +++ b/shared/src/i18n/it/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Nessuno impostato', 'roadtrip.stop.none': 'Una destinazione', 'roadtrip.stop.kindHelp': 'Una sosta lungo il percorso viene disegnata sulla tratta e non viene contata.', + 'roadtrip.stay.mode.pause': 'Sosta', + 'roadtrip.stay.mode.night': 'Pernottamento', + 'roadtrip.stay.checkOutDay': 'Partenza il', + 'roadtrip.stay.dayNumber': 'Giorno {number}', + 'roadtrip.stay.nightAdded': 'Aggiunto come pernottamento', + 'roadtrip.stay.nightAction': 'Aggiungi come pernottamento', 'roadtrip.poi.rest': 'Area di sosta', 'roadtrip.poi.campsite': 'Campeggio', 'roadtrip.poi.food': 'Ristoro', diff --git a/shared/src/i18n/ja/roadtrip.ts b/shared/src/i18n/ja/roadtrip.ts index bcc230370..21ecbce17 100644 --- a/shared/src/i18n/ja/roadtrip.ts +++ b/shared/src/i18n/ja/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': '未設定', 'roadtrip.stop.none': '目的地', 'roadtrip.stop.kindHelp': '途中の立ち寄りは走行線上に描かれ、停車数には数えません。', + 'roadtrip.stay.mode.pause': '休憩', + 'roadtrip.stay.mode.night': '宿泊', + 'roadtrip.stay.checkOutDay': 'チェックアウト日', + 'roadtrip.stay.dayNumber': '{number}日目', + 'roadtrip.stay.nightAdded': '宿泊として追加しました', + 'roadtrip.stay.nightAction': '宿泊として追加', 'roadtrip.poi.rest': 'サービスエリア', 'roadtrip.poi.campsite': 'キャンプ場', 'roadtrip.poi.food': '食事', diff --git a/shared/src/i18n/ko/roadtrip.ts b/shared/src/i18n/ko/roadtrip.ts index 92fc9573e..6625efc92 100644 --- a/shared/src/i18n/ko/roadtrip.ts +++ b/shared/src/i18n/ko/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': '설정 안 됨', 'roadtrip.stop.none': '목적지', 'roadtrip.stop.kindHelp': '경유 정차는 주행 경로에 표시되며 정차 수에 포함되지 않습니다.', + 'roadtrip.stay.mode.pause': '휴식', + 'roadtrip.stay.mode.night': '숙박', + 'roadtrip.stay.checkOutDay': '체크아웃 날짜', + 'roadtrip.stay.dayNumber': '{number}일차', + 'roadtrip.stay.nightAdded': '숙박으로 추가했습니다', + 'roadtrip.stay.nightAction': '숙박으로 추가', 'roadtrip.poi.rest': '휴게소', 'roadtrip.poi.campsite': '캠핑장', 'roadtrip.poi.food': '식사', diff --git a/shared/src/i18n/nl/roadtrip.ts b/shared/src/i18n/nl/roadtrip.ts index 4cd4277a0..caa162ce4 100644 --- a/shared/src/i18n/nl/roadtrip.ts +++ b/shared/src/i18n/nl/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Geen ingesteld', 'roadtrip.stop.none': 'Een bestemming', 'roadtrip.stop.kindHelp': 'Een stop onderweg wordt op de rit getekend en telt niet mee.', + 'roadtrip.stay.mode.pause': 'Pauze', + 'roadtrip.stay.mode.night': 'Overnachten', + 'roadtrip.stay.checkOutDay': 'Uitchecken op', + 'roadtrip.stay.dayNumber': 'Dag {number}', + 'roadtrip.stay.nightAdded': 'Toegevoegd als overnachting', + 'roadtrip.stay.nightAction': 'Toevoegen als overnachting', 'roadtrip.poi.rest': 'Rustplaats', 'roadtrip.poi.campsite': 'Camping', 'roadtrip.poi.food': 'Eten', diff --git a/shared/src/i18n/pl/roadtrip.ts b/shared/src/i18n/pl/roadtrip.ts index cadd4f4be..17249cd7c 100644 --- a/shared/src/i18n/pl/roadtrip.ts +++ b/shared/src/i18n/pl/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Brak ustawionych', 'roadtrip.stop.none': 'Cel podróży', 'roadtrip.stop.kindHelp': 'Postój po drodze rysowany jest na trasie i nie jest liczony.', + 'roadtrip.stay.mode.pause': 'Postój', + 'roadtrip.stay.mode.night': 'Nocleg', + 'roadtrip.stay.checkOutDay': 'Wymeldowanie', + 'roadtrip.stay.dayNumber': 'Dzień {number}', + 'roadtrip.stay.nightAdded': 'Dodano jako nocleg', + 'roadtrip.stay.nightAction': 'Dodaj jako nocleg', 'roadtrip.poi.rest': 'Miejsce odpoczynku', 'roadtrip.poi.campsite': 'Kemping', 'roadtrip.poi.food': 'Jedzenie', diff --git a/shared/src/i18n/ru/roadtrip.ts b/shared/src/i18n/ru/roadtrip.ts index b4b807a99..e2c309045 100644 --- a/shared/src/i18n/ru/roadtrip.ts +++ b/shared/src/i18n/ru/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Не заданы', 'roadtrip.stop.none': 'Пункт назначения', 'roadtrip.stop.kindHelp': 'Остановка в пути рисуется на маршруте и не учитывается в счёте.', + 'roadtrip.stay.mode.pause': 'Остановка', + 'roadtrip.stay.mode.night': 'Ночёвка', + 'roadtrip.stay.checkOutDay': 'Выезд', + 'roadtrip.stay.dayNumber': 'День {number}', + 'roadtrip.stay.nightAdded': 'Добавлено как ночёвка', + 'roadtrip.stay.nightAction': 'Добавить как ночёвку', 'roadtrip.poi.rest': 'Зона отдыха', 'roadtrip.poi.campsite': 'Кемпинг', 'roadtrip.poi.food': 'Еда', diff --git a/shared/src/i18n/sv/roadtrip.ts b/shared/src/i18n/sv/roadtrip.ts index 2efc87400..5c490df95 100644 --- a/shared/src/i18n/sv/roadtrip.ts +++ b/shared/src/i18n/sv/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Inga angivna', 'roadtrip.stop.none': 'Ett resmål', 'roadtrip.stop.kindHelp': 'Ett stopp på vägen ritas på körningen och räknas inte.', + 'roadtrip.stay.mode.pause': 'Paus', + 'roadtrip.stay.mode.night': 'Övernattning', + 'roadtrip.stay.checkOutDay': 'Utcheckning', + 'roadtrip.stay.dayNumber': 'Dag {number}', + 'roadtrip.stay.nightAdded': 'Tillagd som övernattning', + 'roadtrip.stay.nightAction': 'Lägg till som övernattning', 'roadtrip.poi.rest': 'Rastplats', 'roadtrip.poi.campsite': 'Campingplats', 'roadtrip.poi.food': 'Mat', diff --git a/shared/src/i18n/tr/roadtrip.ts b/shared/src/i18n/tr/roadtrip.ts index 6881f2c30..0550743f8 100644 --- a/shared/src/i18n/tr/roadtrip.ts +++ b/shared/src/i18n/tr/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Ayarlanmadı', 'roadtrip.stop.none': 'Bir varış noktası', 'roadtrip.stop.kindHelp': 'Yol üzerindeki mola sürüşe çizilir ve sayıma girmez.', + 'roadtrip.stay.mode.pause': 'Mola', + 'roadtrip.stay.mode.night': 'Konaklama', + 'roadtrip.stay.checkOutDay': 'Çıkış günü', + 'roadtrip.stay.dayNumber': '{number}. gün', + 'roadtrip.stay.nightAdded': 'Konaklama olarak eklendi', + 'roadtrip.stay.nightAction': 'Konaklama olarak ekle', 'roadtrip.poi.rest': 'Dinlenme alanı', 'roadtrip.poi.campsite': 'Kamp alanı', 'roadtrip.poi.food': 'Yemek', diff --git a/shared/src/i18n/uk/roadtrip.ts b/shared/src/i18n/uk/roadtrip.ts index fd92332bd..4c4f90543 100644 --- a/shared/src/i18n/uk/roadtrip.ts +++ b/shared/src/i18n/uk/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Не задано', 'roadtrip.stop.none': 'Пункт призначення', 'roadtrip.stop.kindHelp': 'Зупинка в дорозі малюється на маршруті й не рахується.', + 'roadtrip.stay.mode.pause': 'Зупинка', + 'roadtrip.stay.mode.night': 'Ночівля', + 'roadtrip.stay.checkOutDay': 'Виїзд', + 'roadtrip.stay.dayNumber': 'День {number}', + 'roadtrip.stay.nightAdded': 'Додано як ночівлю', + 'roadtrip.stay.nightAction': 'Додати як ночівлю', 'roadtrip.poi.rest': 'Зона відпочинку', 'roadtrip.poi.campsite': 'Кемпінг', 'roadtrip.poi.food': 'Їжа', diff --git a/shared/src/i18n/vi/roadtrip.ts b/shared/src/i18n/vi/roadtrip.ts index c249535cd..2f00b4aa5 100644 --- a/shared/src/i18n/vi/roadtrip.ts +++ b/shared/src/i18n/vi/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': 'Chưa đặt', 'roadtrip.stop.none': 'Một điểm đến', 'roadtrip.stop.kindHelp': 'Điểm dừng dọc đường được vẽ trên chặng và không tính vào số điểm dừng.', + 'roadtrip.stay.mode.pause': 'Nghỉ', + 'roadtrip.stay.mode.night': 'Qua đêm', + 'roadtrip.stay.checkOutDay': 'Trả phòng ngày', + 'roadtrip.stay.dayNumber': 'Ngày {number}', + 'roadtrip.stay.nightAdded': 'Đã thêm làm nơi nghỉ đêm', + 'roadtrip.stay.nightAction': 'Thêm làm nơi nghỉ đêm', 'roadtrip.poi.rest': 'Trạm dừng nghỉ', 'roadtrip.poi.campsite': 'Khu cắm trại', 'roadtrip.poi.food': 'Đồ ăn', diff --git a/shared/src/i18n/zh-TW/roadtrip.ts b/shared/src/i18n/zh-TW/roadtrip.ts index 0a9ffefad..a08c257fb 100644 --- a/shared/src/i18n/zh-TW/roadtrip.ts +++ b/shared/src/i18n/zh-TW/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': '未設定', 'roadtrip.stop.none': '目的地', 'roadtrip.stop.kindHelp': '途中停靠會畫在行程線上,且不計入停靠數。', + 'roadtrip.stay.mode.pause': '停留', + 'roadtrip.stay.mode.night': '過夜', + 'roadtrip.stay.checkOutDay': '退房日', + 'roadtrip.stay.dayNumber': '第 {number} 天', + 'roadtrip.stay.nightAdded': '已新增為過夜住宿', + 'roadtrip.stay.nightAction': '新增為過夜住宿', 'roadtrip.poi.rest': '休息站', 'roadtrip.poi.campsite': '露營地', 'roadtrip.poi.food': '餐飲', diff --git a/shared/src/i18n/zh/roadtrip.ts b/shared/src/i18n/zh/roadtrip.ts index 555c4b3a8..c1dd71b28 100644 --- a/shared/src/i18n/zh/roadtrip.ts +++ b/shared/src/i18n/zh/roadtrip.ts @@ -32,6 +32,12 @@ const roadtrip: TranslationStrings = { 'roadtrip.limit.none': '未设置', 'roadtrip.stop.none': '目的地', 'roadtrip.stop.kindHelp': '途中停靠会画在行程线上,且不计入停靠数。', + 'roadtrip.stay.mode.pause': '停留', + 'roadtrip.stay.mode.night': '过夜', + 'roadtrip.stay.checkOutDay': '退房日', + 'roadtrip.stay.dayNumber': '第 {number} 天', + 'roadtrip.stay.nightAdded': '已添加为过夜住宿', + 'roadtrip.stay.nightAction': '添加为过夜住宿', 'roadtrip.poi.rest': '服务区', 'roadtrip.poi.campsite': '露营地', 'roadtrip.poi.food': '餐饮',