feat: support check-in time ranges for hotel accommodations

- Add check_in_end column to day_accommodations (Migration 102)
- Server: create/update accommodation accepts check_in_end
- Bidirectional sync: check_in_end synced between accommodation
  and linked reservation metadata (check_in_end_time)
- DayDetailPanel: shows check-in range (e.g. "14:00 – 22:00"),
  new "Until" time picker in hotel form
- ReservationModal: new check-in-until field for hotel bookings
- ReservationsPanel: displays check-in range in metadata cells
- i18n: checkInUntil keys in all 15 languages

Closes #366
This commit is contained in:
Maurice
2026-04-16 00:23:00 +02:00
parent 125436fa87
commit 409a63633c
24 changed files with 84 additions and 27 deletions
+2
View File
@@ -1015,6 +1015,7 @@ const ar: Record<string, string | { name: string; category: string }[]> = {
'reservations.meta.platform': 'المنصة',
'reservations.meta.seat': 'المقعد',
'reservations.meta.checkIn': 'تسجيل الوصول',
'reservations.meta.checkInUntil': 'تسجيل الدخول حتى',
'reservations.meta.checkOut': 'تسجيل المغادرة',
'reservations.meta.linkAccommodation': 'الإقامة',
'reservations.meta.pickAccommodation': 'ربط بالإقامة',
@@ -1499,6 +1500,7 @@ const ar: Record<string, string | { name: string; category: string }[]> = {
'day.noPlacesForHotel': 'أضف أماكن إلى رحلتك أولًا',
'day.allDays': 'الكل',
'day.checkIn': 'تسجيل الوصول',
'day.checkInUntil': 'حتى',
'day.checkOut': 'تسجيل المغادرة',
'day.confirmation': 'التأكيد',
'day.editAccommodation': 'تعديل الإقامة',
+2
View File
@@ -984,6 +984,7 @@ const br: Record<string, string | { name: string; category: string }[]> = {
'reservations.meta.platform': 'Plataforma',
'reservations.meta.seat': 'Assento',
'reservations.meta.checkIn': 'Check-in',
'reservations.meta.checkInUntil': 'Check-in até',
'reservations.meta.checkOut': 'Check-out',
'reservations.meta.linkAccommodation': 'Hospedagem',
'reservations.meta.pickAccommodation': 'Vincular à hospedagem',
@@ -1468,6 +1469,7 @@ const br: Record<string, string | { name: string; category: string }[]> = {
'day.noPlacesForHotel': 'Adicione lugares à viagem primeiro',
'day.allDays': 'Todos',
'day.checkIn': 'Check-in',
'day.checkInUntil': 'Até',
'day.checkOut': 'Check-out',
'day.confirmation': 'Confirmação',
'day.editAccommodation': 'Editar hospedagem',
+2
View File
@@ -1013,6 +1013,7 @@ const cs: Record<string, string | { name: string; category: string }[]> = {
'reservations.meta.platform': 'Nástupiště',
'reservations.meta.seat': 'Sedadlo',
'reservations.meta.checkIn': 'Check-in',
'reservations.meta.checkInUntil': 'Check-in do',
'reservations.meta.checkOut': 'Check-out',
'reservations.meta.linkAccommodation': 'Ubytování',
'reservations.meta.pickAccommodation': 'Propojit s ubytováním',
@@ -1497,6 +1498,7 @@ const cs: Record<string, string | { name: string; category: string }[]> = {
'day.noPlacesForHotel': 'Nejprve přidejte místa ke své cestě',
'day.allDays': 'Vše',
'day.checkIn': 'Check-in',
'day.checkInUntil': 'Do',
'day.checkOut': 'Check-out',
'day.confirmation': 'Potvrzení',
'day.editAccommodation': 'Upravit ubytování',
+2
View File
@@ -1015,6 +1015,7 @@ const de: Record<string, string | { name: string; category: string }[]> = {
'reservations.meta.platform': 'Gleis',
'reservations.meta.seat': 'Sitzplatz',
'reservations.meta.checkIn': 'Check-in',
'reservations.meta.checkInUntil': 'Check-in bis',
'reservations.meta.checkOut': 'Check-out',
'reservations.meta.linkAccommodation': 'Unterkunft',
'reservations.meta.pickAccommodation': 'Mit Unterkunft verknüpfen',
@@ -1499,6 +1500,7 @@ const de: Record<string, string | { name: string; category: string }[]> = {
'day.noPlacesForHotel': 'Füge zuerst Orte zu deiner Reise hinzu',
'day.allDays': 'Alle',
'day.checkIn': 'Check-in',
'day.checkInUntil': 'Bis',
'day.checkOut': 'Check-out',
'day.confirmation': 'Bestätigung',
'day.editAccommodation': 'Unterkunft bearbeiten',
+2
View File
@@ -1068,6 +1068,7 @@ const en: Record<string, string | { name: string; category: string }[]> = {
'reservations.meta.platform': 'Platform',
'reservations.meta.seat': 'Seat',
'reservations.meta.checkIn': 'Check-in',
'reservations.meta.checkInUntil': 'Check-in until',
'reservations.meta.checkOut': 'Check-out',
'reservations.meta.linkAccommodation': 'Accommodation',
'reservations.meta.pickAccommodation': 'Link to accommodation',
@@ -1552,6 +1553,7 @@ const en: Record<string, string | { name: string; category: string }[]> = {
'day.noPlacesForHotel': 'Add places to your trip first',
'day.allDays': 'All',
'day.checkIn': 'Check-in',
'day.checkInUntil': 'Until',
'day.checkOut': 'Check-out',
'day.confirmation': 'Confirmation',
'day.editAccommodation': 'Edit accommodation',
+2
View File
@@ -1448,6 +1448,7 @@ const es: Record<string, string> = {
'day.noPlacesForHotel': 'Añade primero lugares al viaje',
'day.allDays': 'Todos',
'day.checkIn': 'Registro de entrada',
'day.checkInUntil': 'Hasta',
'day.checkOut': 'Registro de salida',
'day.confirmation': 'Confirmación',
'day.editAccommodation': 'Editar alojamiento',
@@ -1615,6 +1616,7 @@ const es: Record<string, string> = {
'reservations.meta.platform': 'Andén',
'reservations.meta.seat': 'Asiento',
'reservations.meta.checkIn': 'Registro de entrada',
'reservations.meta.checkInUntil': 'Check-in hasta',
'reservations.meta.checkOut': 'Registro de salida',
'reservations.meta.linkAccommodation': 'Alojamiento',
'reservations.meta.pickAccommodation': 'Vincular con alojamiento',
+2
View File
@@ -1011,6 +1011,7 @@ const fr: Record<string, string> = {
'reservations.meta.platform': 'Quai',
'reservations.meta.seat': 'Place',
'reservations.meta.checkIn': 'Arrivée',
'reservations.meta.checkInUntil': "Check-in jusqu'à",
'reservations.meta.checkOut': 'Départ',
'reservations.meta.linkAccommodation': 'Hébergement',
'reservations.meta.pickAccommodation': 'Lier à un hébergement',
@@ -1495,6 +1496,7 @@ const fr: Record<string, string> = {
'day.noPlacesForHotel': 'Ajoutez d\'abord des lieux à votre voyage',
'day.allDays': 'Tous',
'day.checkIn': 'Arrivée',
'day.checkInUntil': "Jusqu'à",
'day.checkOut': 'Départ',
'day.confirmation': 'Confirmation',
'day.editAccommodation': 'Modifier l\'hébergement',
+2
View File
@@ -1013,6 +1013,7 @@ const hu: Record<string, string | { name: string; category: string }[]> = {
'reservations.meta.platform': 'Vágány',
'reservations.meta.seat': 'Ülés',
'reservations.meta.checkIn': 'Bejelentkezés',
'reservations.meta.checkInUntil': 'Bejelentkezés eddig',
'reservations.meta.checkOut': 'Kijelentkezés',
'reservations.meta.linkAccommodation': 'Szállás',
'reservations.meta.pickAccommodation': 'Szállás hozzárendelése',
@@ -1496,6 +1497,7 @@ const hu: Record<string, string | { name: string; category: string }[]> = {
'day.noPlacesForHotel': 'Először adj hozzá helyeket az utazásodhoz',
'day.allDays': 'Összes',
'day.checkIn': 'Bejelentkezés',
'day.checkInUntil': 'Eddig',
'day.checkOut': 'Kijelentkezés',
'day.confirmation': 'Visszaigazolás',
'day.editAccommodation': 'Szállás szerkesztése',
+2
View File
@@ -1068,6 +1068,7 @@ const id: Record<string, string | { name: string; category: string }[]> = {
'reservations.meta.platform': 'Peron',
'reservations.meta.seat': 'Kursi',
'reservations.meta.checkIn': 'Check-in',
'reservations.meta.checkInUntil': 'Check-in sampai',
'reservations.meta.checkOut': 'Check-out',
'reservations.meta.linkAccommodation': 'Akomodasi',
'reservations.meta.pickAccommodation': 'Hubungkan ke akomodasi',
@@ -1552,6 +1553,7 @@ const id: Record<string, string | { name: string; category: string }[]> = {
'day.noPlacesForHotel': 'Tambahkan tempat ke perjalananmu terlebih dahulu',
'day.allDays': 'Semua',
'day.checkIn': 'Check-in',
'day.checkInUntil': 'Sampai',
'day.checkOut': 'Check-out',
'day.confirmation': 'Konfirmasi',
'day.editAccommodation': 'Edit akomodasi',
+2
View File
@@ -1012,6 +1012,7 @@ const it: Record<string, string | { name: string; category: string }[]> = {
'reservations.meta.platform': 'Binario',
'reservations.meta.seat': 'Posto',
'reservations.meta.checkIn': 'Check-in',
'reservations.meta.checkInUntil': 'Check-in fino a',
'reservations.meta.checkOut': 'Check-out',
'reservations.meta.linkAccommodation': 'Alloggio',
'reservations.meta.pickAccommodation': 'Collega a un alloggio',
@@ -1496,6 +1497,7 @@ const it: Record<string, string | { name: string; category: string }[]> = {
'day.noPlacesForHotel': 'Aggiungi prima i luoghi al tuo viaggio',
'day.allDays': 'Tutti',
'day.checkIn': 'Check-in',
'day.checkInUntil': 'Fino a',
'day.checkOut': 'Check-out',
'day.confirmation': 'Conferma',
'day.editAccommodation': 'Modifica alloggio',
+2
View File
@@ -1011,6 +1011,7 @@ const nl: Record<string, string> = {
'reservations.meta.platform': 'Perron',
'reservations.meta.seat': 'Stoel',
'reservations.meta.checkIn': 'Inchecken',
'reservations.meta.checkInUntil': 'Check-in tot',
'reservations.meta.checkOut': 'Uitchecken',
'reservations.meta.linkAccommodation': 'Accommodatie',
'reservations.meta.pickAccommodation': 'Koppel aan accommodatie',
@@ -1495,6 +1496,7 @@ const nl: Record<string, string> = {
'day.noPlacesForHotel': 'Voeg eerst plaatsen toe aan je reis',
'day.allDays': 'Alle',
'day.checkIn': 'Inchecken',
'day.checkInUntil': 'Tot',
'day.checkOut': 'Uitchecken',
'day.confirmation': 'Bevestiging',
'day.editAccommodation': 'Accommodatie bewerken',
+2
View File
@@ -968,6 +968,7 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
'reservations.meta.platform': 'Peron',
'reservations.meta.seat': 'Miejsce',
'reservations.meta.checkIn': 'Zameldowanie',
'reservations.meta.checkInUntil': 'Check-in do',
'reservations.meta.checkOut': 'Wymeldowanie',
'reservations.meta.linkAccommodation': 'Zakwaterowanie',
'reservations.meta.pickAccommodation': 'Link do zakwaterowania',
@@ -1450,6 +1451,7 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
'day.noPlacesForHotel': 'Najpierw dodaj miejsca do swojej podróży',
'day.allDays': 'Wszystkie',
'day.checkIn': 'Zameldowanie',
'day.checkInUntil': 'Do',
'day.checkOut': 'Wymeldowanie',
'day.confirmation': 'Potwierdzenie',
'day.editAccommodation': 'Edytuj zakwaterowanie',
+2
View File
@@ -1011,6 +1011,7 @@ const ru: Record<string, string> = {
'reservations.meta.platform': 'Платформа',
'reservations.meta.seat': 'Место',
'reservations.meta.checkIn': 'Заезд',
'reservations.meta.checkInUntil': 'Заселение до',
'reservations.meta.checkOut': 'Выезд',
'reservations.meta.linkAccommodation': 'Жильё',
'reservations.meta.pickAccommodation': 'Привязать к жилью',
@@ -1495,6 +1496,7 @@ const ru: Record<string, string> = {
'day.noPlacesForHotel': 'Сначала добавьте места в поездку',
'day.allDays': 'Все',
'day.checkIn': 'Заезд',
'day.checkInUntil': 'До',
'day.checkOut': 'Выезд',
'day.confirmation': 'Подтверждение',
'day.editAccommodation': 'Редактировать жильё',
+2
View File
@@ -1011,6 +1011,7 @@ const zh: Record<string, string> = {
'reservations.meta.platform': '站台',
'reservations.meta.seat': '座位',
'reservations.meta.checkIn': '入住',
'reservations.meta.checkInUntil': '入住截止',
'reservations.meta.checkOut': '退房',
'reservations.meta.linkAccommodation': '住宿',
'reservations.meta.pickAccommodation': '关联住宿',
@@ -1495,6 +1496,7 @@ const zh: Record<string, string> = {
'day.noPlacesForHotel': '请先在旅行中添加地点',
'day.allDays': '全部',
'day.checkIn': '入住',
'day.checkInUntil': '截止',
'day.checkOut': '退房',
'day.confirmation': '确认号',
'day.editAccommodation': '编辑住宿',
+2
View File
@@ -1067,6 +1067,7 @@ const zhTw: Record<string, string> = {
'reservations.meta.platform': '站臺',
'reservations.meta.seat': '座位',
'reservations.meta.checkIn': '入住',
'reservations.meta.checkInUntil': '入住截止',
'reservations.meta.checkOut': '退房',
'reservations.meta.linkAccommodation': '住宿',
'reservations.meta.pickAccommodation': '關聯住宿',
@@ -1551,6 +1552,7 @@ const zhTw: Record<string, string> = {
'day.noPlacesForHotel': '請先在旅行中新增地點',
'day.allDays': '全部',
'day.checkIn': '入住',
'day.checkInUntil': '截止',
'day.checkOut': '退房',
'day.confirmation': '確認號',
'day.editAccommodation': '編輯住宿',