feat(dashboard): mobile layout, glass UI, context bottom nav + OIDC PKCE (#1079)

* feat(dashboard): mobile layout, glass tiles, plain-text countdown, place photos

- Rework the mobile dashboard: cover hero, separate boarding-pass card,
  trimmed atlas (trips + days only), stacked widgets
- New floating bottom tab bar with a centred context-aware + button
  (new trip / place / journey / entry depending on the page)
- Move profile + notifications into a small top strip on the dashboard
- Desktop: glassmorphic tiles (light + dark), neutral dark palette,
  plain-text countdown module, real place photos in the boarding pass

* i18n(dashboard): translate new dashboard keys across all locales

Fill the dashboard-rework keys (hero, atlas, fx, tz, upcoming, copy
dialog, aria labels, countdown) that were left as English placeholders,
plus the new startsIn/aria keys, for all 19 languages.

* feat(oidc): send PKCE (S256) in the OIDC login flow

The OIDC client now generates a code_verifier per login, sends the
S256 code_challenge on the authorize request and the code_verifier on
the token exchange. Works whether the provider has PKCE optional or
required (fixes login against providers that require PKCE, e.g. Pocket ID).
This commit is contained in:
Maurice
2026-05-27 23:19:03 +02:00
committed by GitHub
parent 0d2657ee37
commit 6d2dd37414
34 changed files with 1692 additions and 1296 deletions
+59 -50
View File
@@ -9,7 +9,7 @@ const dashboard: TranslationStrings = {
'dashboard.subtitle.activeMany': '{count} aktív utazás',
'dashboard.subtitle.archivedSuffix': ' · {count} archivált',
'dashboard.newTrip': 'Új utazás',
'dashboard.newTripSub': 'Start blank · or import from another planner',
'dashboard.newTripSub': 'Tervezz egy új utazást a nulláról',
'dashboard.gridView': 'Rácsnézet',
'dashboard.listView': 'Listanézet',
'dashboard.currency': 'Pénznem',
@@ -105,55 +105,64 @@ const dashboard: TranslationStrings = {
'dashboard.mobile.inMonths': '{count} hónap múlva',
'dashboard.mobile.completed': 'Befejezett',
'dashboard.mobile.currencyConverter': 'Pénznemváltó',
'dashboard.filter.planned': 'Planned',
'dashboard.hero.badgeLive': 'LIVE NOW',
'dashboard.hero.badgeToday': 'STARTS TODAY',
'dashboard.hero.badgeTomorrow': 'TOMORROW',
'dashboard.hero.badgeNext': 'UP NEXT',
'dashboard.hero.badgeRecent': 'RECENT',
'dashboard.hero.tripDates': 'Trip dates',
'dashboard.hero.noDates': 'No dates set',
'dashboard.hero.travelerOne': '{count} traveler',
'dashboard.hero.travelerMany': '{count} travelers',
'dashboard.hero.destinationOne': '{count} destination',
'dashboard.hero.destinationMany': '{count} destinations',
'dashboard.hero.dayUnitOne': 'day',
'dashboard.hero.dayUnitMany': 'days',
'dashboard.hero.dayLeft': 'Day left',
'dashboard.hero.daysLeft': 'Days left',
'dashboard.hero.lastDay': 'Last day',
'dashboard.atlas.countriesVisited': 'Atlas · Countries visited',
'dashboard.atlas.ofTotal': 'of {total}',
'dashboard.atlas.tripsTotal': 'Trips total',
'dashboard.atlas.placesMapped': '{count} places mapped',
'dashboard.atlas.daysTraveled': 'Days traveled',
'dashboard.atlas.daysUnit': 'days',
'dashboard.atlas.acrossAllTrips': 'across all trips',
'dashboard.atlas.distanceFlown': 'Distance flown',
'dashboard.filter.planned': 'Tervezett',
'dashboard.hero.badgeLive': 'MOST ÉLŐBEN',
'dashboard.hero.badgeToday': 'MA KEZDŐDIK',
'dashboard.hero.badgeTomorrow': 'HOLNAP',
'dashboard.hero.badgeNext': 'KÖVETKEZŐ',
'dashboard.hero.badgeRecent': 'LEGUTÓBBI',
'dashboard.hero.tripDates': 'Utazás dátumai',
'dashboard.hero.noDates': 'Nincs dátum megadva',
'dashboard.hero.travelerOne': '{count} utazó',
'dashboard.hero.travelerMany': '{count} utazó',
'dashboard.hero.destinationOne': '{count} úti cél',
'dashboard.hero.destinationMany': '{count} úti cél',
'dashboard.hero.dayUnitOne': 'nap',
'dashboard.hero.dayUnitMany': 'nap',
'dashboard.hero.dayLeft': 'nap van hátra',
'dashboard.hero.daysLeft': 'nap van hátra',
'dashboard.hero.lastDay': 'Utolsó nap',
'dashboard.hero.untilStart': 'Indulásig',
'dashboard.hero.startsIn': 'Indulásig',
'dashboard.atlas.countriesVisited': 'Atlas · Meglátogatott országok',
'dashboard.atlas.ofTotal': '/ {total}',
'dashboard.atlas.tripsTotal': 'Utazások összesen',
'dashboard.atlas.placesMapped': '{count} hely a térképen',
'dashboard.atlas.daysTraveled': 'Utazási napok',
'dashboard.atlas.daysUnit': 'nap',
'dashboard.atlas.acrossAllTrips': 'az összes utazásban',
'dashboard.atlas.distanceFlown': 'Megtett távolság',
'dashboard.atlas.kmUnit': 'km',
'dashboard.atlas.aroundEquator': '≈ {count}× around the equator',
'dashboard.card.idea': 'Idea',
'dashboard.card.buddyOne': 'Buddy',
'dashboard.fx.from': 'From',
'dashboard.fx.to': 'To',
'dashboard.fx.unavailable': 'Rate unavailable',
'dashboard.tz.searchPlaceholder': 'Search timezone…',
'dashboard.tz.empty': 'No other timezones yet — add one with +',
'dashboard.upcoming.title': 'Upcoming reservations',
'dashboard.upcoming.empty': 'Nothing booked yet.',
'dashboard.confirm.copy.title': 'Copy this trip?',
'dashboard.confirm.copy.willCopy': 'Will be copied',
'dashboard.confirm.copy.will1': 'Days, places & day assignments',
'dashboard.confirm.copy.will2': 'Accommodations & reservations',
'dashboard.confirm.copy.will3': 'Budget items & category order',
'dashboard.confirm.copy.will4': 'Packing lists (unchecked)',
'dashboard.confirm.copy.will5': 'TODOs (unassigned & unchecked)',
'dashboard.confirm.copy.will6': 'Day notes',
'dashboard.confirm.copy.wontCopy': 'Won\'t be copied',
'dashboard.confirm.copy.wont1': 'Collaborators & member assignments',
'dashboard.confirm.copy.wont2': 'Collab notes, polls & messages',
'dashboard.confirm.copy.wont3': 'Files & photos',
'dashboard.confirm.copy.wont4': 'Share tokens',
'dashboard.confirm.copy.confirm': 'Copy trip',
'dashboard.atlas.aroundEquator': '≈ {count}× az Egyenlítő körül',
'dashboard.card.idea': 'Ötlet',
'dashboard.card.buddyOne': 'Útitárs',
'dashboard.fx.from': 'Erről',
'dashboard.fx.to': 'Erre',
'dashboard.fx.unavailable': 'Árfolyam nem elérhető',
'dashboard.tz.searchPlaceholder': 'Időzóna keresése…',
'dashboard.tz.empty': 'Még nincs több időzóna — adj hozzá egyet a + gombbal',
'dashboard.upcoming.title': 'Közelgő foglalások',
'dashboard.upcoming.empty': 'Még nincs semmi lefoglalva.',
'dashboard.confirm.copy.title': 'Másolja ezt az utazást?',
'dashboard.confirm.copy.willCopy': 'Másolásra kerül',
'dashboard.confirm.copy.will1': 'Napok, helyek és napi hozzárendelések',
'dashboard.confirm.copy.will2': 'Szállások és foglalások',
'dashboard.confirm.copy.will3': 'Költségtételek és kategóriasorrend',
'dashboard.confirm.copy.will4': 'Csomaglisták (kipipálatlan)',
'dashboard.confirm.copy.will5': 'Teendők (hozzárendelés és pipa nélkül)',
'dashboard.confirm.copy.will6': 'Napi jegyzetek',
'dashboard.confirm.copy.wontCopy': 'Nem kerül másolásra',
'dashboard.confirm.copy.wont1': 'Közreműködők és tag-hozzárendelések',
'dashboard.confirm.copy.wont2': 'Közös jegyzetek, szavazások és üzenetek',
'dashboard.confirm.copy.wont3': 'Fájlok és fotók',
'dashboard.confirm.copy.wont4': 'Megosztási tokenek',
'dashboard.confirm.copy.confirm': 'Utazás másolása',
'dashboard.aria.toggleView': 'Nézet váltása',
'dashboard.aria.filter': 'Szűrő',
'dashboard.aria.duplicate': 'Duplikálás',
'dashboard.aria.refreshRates': 'Árfolyamok frissítése',
'dashboard.aria.swapCurrencies': 'Pénznemek cseréje',
'dashboard.aria.addTimezone': 'Időzóna hozzáadása',
'dashboard.aria.removeTimezone': '{city} eltávolítása',
};
export default dashboard;