mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-24 07:41:47 +00:00
62723b37e8524d44e96ffc56f6790b1dca28c5b2
43 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
17822aa9eb |
fix(days): align note time limit to 250 and keep toasts above modal blur (#1252)
The day-note 'time' field capped at 150 server-side while the dialog and shared schema allow 250, so 151-250 char notes 400'd with a confusing 'time must be 150...' message. Raise the controller and MCP limits to 250. Also lift the toast container above modal overlays so the error toast isn't rendered behind the modal's backdrop blur. |
||
|
|
ad893eb1cc |
Release 3.1.0 (#1185)
* Phase 0 — NestJS + Zod foundation harness (F1–F8) (#1050) Co-hosted NestJS app behind the existing Express server via a strangler-fig dispatcher, sharing the same better-sqlite3 connection and JWT httpOnly cookie. Additive and dormant: default routing stays on Express, Nest only serves its own /api/_nest diagnostics until a module opts in. F1 @trek/shared Zod contract package; F2 Nest bootstrap co-hosted (fall-through, single Dockerfile/port); F3 shared better-sqlite3 provider; F4 JWT cookie auth guard (+ @CurrentUser, admin guard); F5 Zod validation pipe + error-envelope parity; F6 Nest test + coverage gates; F7 per-prefix strangler toggle (env, default Express); F8 CI build/typecheck/test/coverage. Remaining F4/F6/F8 checklist items (trip-access + permission levels + MFA policy, e2e harness/seed + 80% gate, Nest↔Express parity test, Playwright PR-comment workflow) are tracked on the first consuming module cards (L1/A1/C1). * feat(weather): migrate /api/weather to the NestJS pilot module (L1) (#1053) First strangler migration (L1): /api/weather is served by a NestJS module. - @trek/shared/weather Zod contract; Nest controller byte-identical to the legacy Express route (paths, query params, status codes, { error } bodies, lang default, ApiError/500 passthrough). Service reuses getWeather/getDetailedWeather (+ shared cache; MCP tools unchanged). - Strangler routes /api/weather to Nest by default; the legacy Express route + its migration-time parity test were decommissioned in this PR. - Frontend (FE2): weatherApi typed against the @trek/shared WeatherResult contract. - Harness: reusable Nest-vs-Express parity harness, e2e harness (temp SQLite + seed/cookie helpers, real JwtAuthGuard), src/nest coverage gate raised to >=80%, src/nest test guide. - Verified end-to-end on a prod mirror (dev1): 401/400/200 via Nest with real Open-Meteo data, Express route gone. * fix(packing): multiply item weight by quantity in bag/total weight calcs (#898) Quantity now counts toward bag and total weights. Generalised to an itemWeight() helper used by every weight sum (bag totals + max, unassigned, grand total; sidebar + bag modal) with unit tests. * feat(i18n): add Korean (ko) translation (#977) Korean translation by @ppuassi, topped up to full en.ts key parity. Language registration follows separately. * feat(i18n): add Japanese (ja) translation (#829) Japanese translation by @soma3978, at full en.ts key parity, registered in supportedLanguages + TranslationContext. * Add Turkish (tr) translation + language registry (#1029) Turkish translation by @SkyLostTR, at full en.ts key parity, registered in supportedLanguages + TranslationContext. * i18n: register Korean + add Ukrainian translation (#1055) Korean translation by @ppuassi (#977) — now registered. Ukrainian by @JeffyOLOLO (#902) — lifted onto a clean branch. Both at full en.ts key parity (2258 keys). * chore: fix monorepo build pipeline and migrate shared to built package (#1056) * chore: fix monorepo build pipeline and migrate shared to built package - Root package.json: add workspace scripts (dev, build, test, test:cov, test:e2e) that delegate to actual scripts in shared/server/client workspaces - shared: add tsup build step (CJS + ESM dual output, .d.ts); consumers now import from the built dist instead of raw TS source via path aliases - server: replace tsc-alias with tsconfig-paths (tsc-alias mangled node_modules paths); fix MCP SDK path aliases to point to root node_modules (../node_modules) - server/scripts/dev.mjs: delay node --watch until tsc -w signals first-pass done, eliminating the spurious restart on every dev startup - client/vite.config.js + vitest.config.ts: remove @trek/shared path alias (no longer needed now that shared is a proper package) - Consolidate package-lock.json at the workspace root; drop per-workspace lock files * chore: fix test script to reflect root package.json * chore: add missing lint and prettier script in root package.json * fix(ci): build shared before tests; fix vitest MCP SDK alias paths vitest.config.ts aliases pointed at ./node_modules/ (server-local) but packages are hoisted to the root node_modules/ in the npm workspace — changed to ../node_modules/. CI jobs now install and build shared before running server/client tests so that @trek/shared's dist/ exists when vitest resolves the package. * fix(docker): update Dockerfile and CI for monorepo workspace structure Dockerfile: - Add shared-builder stage that produces @trek/shared dist before client and server stages need it - Each build stage carries root package.json + package-lock.json so npm can resolve @trek/shared as a workspace dependency - Production stage installs via workspace context (npm ci --workspace=server --omit=dev) so node_modules/@trek/shared symlinks to shared/dist correctly - Copy server/tsconfig.json into the image so tsconfig-paths/register can find the MCP SDK path aliases at runtime - CMD cds into /app/server before starting node so tsconfig-paths baseUrl resolves and ../node_modules points to /app/node_modules - Remove mkdir for /app/server (now a real dir); keep symlinks for uploads/data docker.yml version-bump: - Replace manual per-workspace cd+npm-version calls with single: npm version --workspaces --include-workspace-root --no-git-tag-version (mirrors the version:* scripts in root package.json) - git add now references root package-lock.json; adds shared/package.json .dockerignore: add shared/dist package.json: fix version:prerelease preid (alpha → pre) * fix(tests): use in-memory SQLite per worker in test mode vitest pool:forks spawns parallel worker processes that all called initDb() on the same data/travel.db, causing SQLite "database is locked" and "duplicate column name" races. When NODE_ENV=test each fork now gets an isolated :memory: DB so migrations run independently with no file contention. * chore(ci): add ACT guards to skip DockerHub steps in local act runs act sets ACT=true automatically. Guards added: - docker login: if: ${{ !env.ACT }} - build outputs: type=docker (local load) when ACT, push-by-digest when CI - digest export/upload: if: ${{ !env.ACT }} - merge job: if: ${{ !env.ACT }} - release-helm job (docker.yml): if: ${{ !env.ACT }} - version-bump git push (docker.yml): wrapped in [ -z "$ACT" ] shell guard Run locally with: ./bin/act -j build -W .github/workflows/docker.yml \ -P ubuntu-latest=catthehacker/ubuntu:act-latest * fix(ci): move ACT guards to step level; add guards to security.yml env context is invalid in job-level if conditions — moved all ACT guards down to individual steps. Also guards docker login + scout in security.yml so act can run the build-only part of that workflow. * fix(ci): skip git fetch and tag logic in act (no remote access in local containers) * Revert "fix(ci): skip git fetch and tag logic in act (no remote access in local containers)" This reverts commit |
||
|
|
86ee8044da |
v3.0.22 Bug Fixes & Improvements (#1041)
Bundles the v3.0.22 bug fixes and improvements. See the release notes for the full list. |
||
|
|
58218ff5f6 |
fix(oidc,ui): restore Authentik login and fix mobile delete dialog (#845)
OIDC: when OIDC_DISCOVERY_URL is explicitly set, trust the discovery doc's issuer for id_token comparison instead of rejecting a path mismatch as an error. Authentik (and similar realm-path providers) return a canonical issuer like /application/o/<slug>/ that differs from the operator's base OIDC_ISSUER. Strict equality blocked login in 3.x despite working in v2. Default discovery (no custom URL) keeps the strict check. Adds OIDC-SVC-037/038/039. UI: ConfirmDialog and CopyTripDialog lacked the --bottom-nav-h paddingBottom offset that other overlays already use. On mobile portrait the action buttons were hidden behind the sticky bottom nav bar. Closes #843 Closes #844 |
||
|
|
bd6cd55a13 | fix(journey): resolve issues #789-801 — mobile layout, day colors, location formatting, date picker, public share UX | ||
|
|
9e5100c71c |
fix: keep modal save button visible on mobile (#803, #804)
Two fixes in Modal.tsx: - Replace 100vh with 100dvh so iOS Safari PWA respects the actual visible viewport. Explicitly subtract --bottom-nav-h on mobile so the modal never extends behind the tab bar. - overflow-hidden on the container so the footer's bottom corners inherit rounded-2xl. - flex-shrink-0 on header and footer + min-h-0 on the body so the body shrinks and scrolls while the footer stays put. One fix in PlaceFormModal.tsx: - Save/cancel were rendered inside the scrollable body. Moved them into the Modal's footer slot. |
||
|
|
09431f725c |
feat(dashboard): add pre-copy confirmation modal showing what will and won't be copied
Introduces CopyTripDialog — a two-section modal that appears before the copy action and lists what is carried over (days, places, budget items, packing lists, TODOs, notes) and what is intentionally skipped (collaborators, collab data, files, share tokens). Addresses the UX gap raised in #786. |
||
|
|
3450bd59f8 |
feat: show date badge on day selectors + i18n transport modal titles
Day selectors in the Transport, Reservation and Hotel-Day-Range modals only showed the renamed day title once a day had a custom name — hiding the actual date. Added an optional badge prop to CustomSelect, rendered as a pill next to the label, and wired the date badge onto all affected dropdowns. FileManager day section headers got the same pill for consistency. Also translated transport.addTransport and transport.modalTitle.* in all 13 non-English language files; the keys existed but still carried the English source string. |
||
|
|
4db6cbef22 | add Emil-style UI polish pass (animations, shared components, feel) | ||
|
|
38f4c9aecb |
refine places sidebar: filter counts, compact select UI, tooltip component
- replace "Auswählen" button with small Check↔X toggle next to category dropdown - move bulk-action bar below search, icon-only buttons (Select all, Delete) - filter tabs as pill buttons with per-filter count badges - shared Tooltip component (portaled, delayed) replaces native title - apply tooltip to select toggle, bulk actions, add note, add transport - rename places.importFile: "Datei importieren" -> "Dateimport" |
||
|
|
6a718fccea |
feat(import): selective GPX/KML element import and performance improvements
Add type-selector UI in the file import modal letting users choose which GPX elements (waypoints, routes, tracks) or KML/KMZ elements (points, paths) to import. KML LineString placemarks are now imported as path places with route_geometry. Performance improvements: - Extract MemoPlaceRow with React.memo and contentVisibility:auto to cut unnecessary re-renders in PlacesSidebar - Add weatherQueue to cap concurrent weather fetches at 3 - Replace sequential per-place deletes with a single bulkDelete API call (new DELETE /places/bulk endpoint + deletePlacesMany service) - Memoize atlas/photo/weather service calls to avoid redundant requests - Add multi-select mode to PlacesSidebar for bulk operations Add large GPX/KML/KMZ fixtures for integration/perf testing and two profiler analysis scripts under scripts/. |
||
|
|
9c2decb095 |
fix(maps): reduce Google Places API quota usage with persistent caching
P0 — stop the bleeding:
- Honor place.image_url in MapView and TripPlannerPage to skip redundant fetchPhoto calls
- Trim Place Details field mask (drop reviews/editorialSummary from default; new getPlaceDetailsExpanded for inspector)
- Admin toggle places_photos_enabled (default ON) to kill Google photo fetches under quota pressure; Wikimedia unaffected
- Return { photoUrl: null } instead of 204 so client handles disabled state cleanly
P1 — structural fix:
- New placePhotoCache service: persistent disk cache at uploads/photos/google/<sha1>.jpg, atomic writes, stampede dedup via in-flight Map
- Migrations 105-107: google_place_photo_meta table, place_details_cache table, backfill signed Google URLs to stable proxy URLs
- getPlacePhoto rewrites to fetch image bytes directly, store on disk, return /api/maps/place-photo/:id/bytes proxy URL
- Stable proxy URLs written to places.image_url — survive container restarts, no expiry
- New GET /api/maps/place-photo/:placeId/bytes route serving cached files with long-lived Cache-Control
- Place Details DB row cache with 7-day TTL; ?refresh=1 escape hatch
- photoService fast-path: proxy URLs bypass the mapsApi round-trip and go straight to urlToBase64
Bug fixes:
- MapView now requests base64 thumbs for places with proxy image_url (markers were showing color fallback)
- createPlaceIcon accepts /api/maps/place-photo/ URLs as interim fallback while thumb generates
- setSelectedAssignmentId ReferenceError in mobile day-detail handler (use selectAssignment)
- Remove redundant decodeURIComponent on already-decoded Express route param
- Use SHA1 hash for disk filenames to prevent coords:lat:lng pseudo-ID collisions
- Add checkSsrf guard to Wikimedia byte fetch
- Tighten migration 107 LIKE filter to avoid rewriting manually-pasted Google image URLs
- Validate enabled is boolean on PUT /admin/places-photos
- Drop aggressive iconCache.clear() on every thumb arrival
Observability:
- googleFetch() wrapper counts and debug-logs every outbound Google API call with running total
|
||
|
|
fef12b0e8b |
fix(mobile): account for bottom navbar in overlays and improve system notices UX
- Add paddingBottom: var(--bottom-nav-h) to all mobile overlays that were clipping content behind the bottom navbar: EntryEditor, SystemNoticeModal, JourneyPage create modal, TodoListPanel sheets, TripPlannerPage PlaceInspector, PackingListPanel bag modal, both PhotoLightboxes, FileManager viewer, and shared Modal primitive - Replace single-notice mobile bottom sheet with a 3-slot horizontal strip so adjacent notices are physically present during drag - Add live-follow swipe left/right to navigate between notices with spring-back when under threshold and flushSync to eliminate blink on commit - Add live-follow swipe down to dismiss all notices with spring-back; backdrop tap also triggers the slide-down animation - Normalize notice height with useLayoutEffect minHeight on strip and align-items: stretch so all slots are always the tallest notice height - Pin CTA button at consistent Y across notices via flex-1 + mt-auto; always render invisible Not now placeholder to equalise CTA section height - Move pager dots/counter below CTA buttons |
||
|
|
0104ecfee8 |
fix(mobile): prevent bottom nav from clipping scrollable content and dialogs
- Add --bottom-nav-h CSS token (84px + safe-area on mobile, 0px on desktop) to give all fixes a single source of truth for the nav height - Apply token to JourneySettingsDialog (fixes #650) and PlacesSidebar day-picker sheet so bottom-anchored sheets clear the nav bar - Add paddingBottom to TripPlannerPage Bookings, Lists, and Budget tab scroll containers so content can be scrolled past the nav - Bump Modal z-index from z-50 to z-[200] so modals render above the bottom nav (both share z-50 with nav winning by DOM order) |
||
|
|
956c4270df |
merge: resolve conflicts with dev, fix 7 Snyk security issues
- Resolve translation conflicts (keep both journey + OAuth scope keys) - Resolve migrations.ts (dev OAuth migrations + journey migrations) - Fix hono directory traversal, response splitting, input validation (CVE-2026-39407/08/09/10) - Fix @hono/node-server directory traversal (CVE-2026-39406) - Fix nodemailer CRLF injection (upgrade to 8.0.5) |
||
|
|
13956804c2 |
feat: Journey addon — travel journal with entries, photos, public sharing & PDF export
- 5-table schema (journeys, entries, photos, trips, contributors) with migrations 87-91 - Trip-to-Journey sync engine with skeleton entries and photo sync - Full CRUD API for journeys, entries, photos with Immich/Synology integration - Timeline, Gallery and Map views with entry editor (markdown, mood, weather, pros/cons) - Journey frontpage with hero card, stats and trip suggestions - Public share links with token-based access and photo proxy - PDF photo book export (Polarsteps-inspired) - Dashboard redesign: mobile greeting, live trip hero, quick actions, unified card design - BottomNav profile sheet with settings/admin/logout - DayPlan mobile inline place picker - TripFormModal members management - Vacay calendar trip date indicator dots - Fix contributor photo access (403) for journey Immich/Synology photos - Trip deletion cleanup for journey skeleton entries - i18n: 231 new keys across all 14 languages (native translations, no fallbacks) |
||
|
|
535c06bb3f |
feat(mcp): granular OAuth scopes and per-client rate limiting
- Split `media:read` into `geo:read` and `weather:read` scopes - Add dedicated `atlas:read/write` scopes (previously under `places`) - Add dedicated `todos:read/write` scopes (previously under `collab`) - Rate limiting now keyed by userId+clientId instead of userId alone - Bind MCP sessions to the OAuth client that created them - Log MCP tool calls to audit log with clientId - Invalidate all MCP sessions on addon state change - Reduce session sweep interval from 10min to 1min - Update all translations with new scope labels |
||
|
|
d4bb8be86b |
test: expand frontend test suite to 82% coverage
Adds ~45 new and updated test files covering Admin, Collab, Dashboard, Map, Memories, PDF, Photos, Planner, Settings, Vacay, Weather components, pages, stores, and a WebSocket integration test. |
||
|
|
fd48169219 |
test(client): expand frontend test suite to 69.1% coverage
Add and extend tests across 32 files (+10 595 lines) covering Admin panels (AuditLog, Backup, DevNotifications, GitHub), Collab (Chat, Notes, Panel, Polls), Planner (DayDetailPanel, DayPlanSidebar), Settings (DisplaySettings, Integrations, MapSettings), Files (FileManager, FilesPage), Map, Layout (DemoBanner, InAppNotificationBell), shared pickers (CustomDateTimePicker, CustomTimePicker), Vacay holidays, pages (Dashboard, Login), unit stores (authStore, inAppNotificationStore), API (authUrl, client integration), and i18n. Also updates sonar-project.properties and MSW trip handlers to support the new cases. |
||
|
|
3c31902885 | test(front): add test suite frontend (WIP) | ||
|
|
897e1bff26 |
fix(dates): use UTC parsing and display for date-only strings (#351)
Date-only strings parsed with new Date(dateStr + 'T00:00:00') were
interpreted relative to the local timezone, causing off-by-one day
display for users west of UTC. Fixed across 16 files by parsing as
UTC ('T00:00:00Z') and displaying with timeZone: 'UTC'.
|
||
|
|
95cb81b0e5 |
perf: major trip planner performance overhaul (#218)
Store & re-render optimization: - TripPlannerPage uses selective Zustand selectors instead of full store - placesSlice only updates affected days on place update/delete - Route calculation only reacts to selected day's assignments - DayPlanSidebar uses stable action refs instead of full store Map marker performance: - Shared photoService for PlaceAvatar and MapView (single cache, no duplicate requests) - Client-side base64 thumbnail generation via canvas (CORS-safe for Wikimedia) - Map markers use base64 data URL <img> tags for smooth zoom (no external image decode) - Sidebar uses same base64 thumbnails with IntersectionObserver for visible-first loading - Icon cache prevents duplicate L.divIcon creation - MarkerClusterGroup with animate:false and optimized chunk settings - Photo fetch deduplication and batched state updates Server optimizations: - Wikimedia image size reduced to 400px (from 600px) - Photo cache: 5min TTL for errors (was 12h), prevents stale 404 caching - Removed unused image-proxy endpoint UX improvements: - Splash screen with plane animation during initial photo preload - Markdown rendering in DayPlanSidebar place descriptions - Missing i18n keys added, all 12 languages synced to 1376 keys |
||
|
|
4ebf9c5f11 |
feat: add expense date and CSV export to budget
- New expense_date column on budget items (DB migration #42) - Date column in budget table with custom date picker - CSV export button with BOM, semicolon separator, localized dates, currency in header, per-person/day calculations - CustomDatePicker compact/borderless modes for inline table use - i18n keys for all 12 languages |
||
|
|
23edfe3dfc |
fix: harden permissions system after code review
- Gate permissions in /app-config behind optionalAuth so unauthenticated requests don't receive admin configuration - Fix trip_delete isMember parameter (was hardcoded false) - Return skipped keys from savePermissions for admin visibility - Add disabled prop to CustomSelect, use in BudgetPanel currency picker - Fix CollabChat reaction handler returning false instead of void - Pass canUploadFiles as prop to NoteFormModal instead of internal store read - Make edit-only NoteFormModal props optional (onDeleteFile, note, tripId) - Add missing trailing newlines to .gitignore and it.ts |
||
|
|
3444e3f446 |
Merge branch 'perf-test' of https://github.com/jubnl/TREK into dev
# Conflicts: # client/src/components/Map/MapView.tsx |
||
|
|
ce7215341f |
fix: 12h time format input and display in bookings
- Allow typing AM/PM in time input when 12h format is active - Format end time correctly in reservations panel (handle time-only strings) |
||
|
|
9a949d7391 | Performance on trip planner (Maybe ?) | ||
|
|
a314ba2b80 |
feat: public read-only share links with permissions — closes #79
Share links: - Generate a public link in the trip share modal - Choose what to share: Map & Plan, Bookings, Packing, Budget, Chat - Permissions enforced server-side - Delete link to revoke access instantly Shared trip page (/shared/:token): - Read-only view with TREK logo, cover image, trip details - Tabbed navigation with Lucide icons (responsive on mobile) - Interactive map with auto-fit bounds per day - Day plan, Bookings, Packing, Budget, Chat views - Language picker, TREK branding footer Technical: - share_tokens DB table with per-field permissions - Public GET /shared/:token endpoint (no auth) - Two-column share modal (max-w-5xl) |
||
|
|
a6a7edf0b2 |
feat: bucket list POIs with auto-search + optional dates — closes #105
- Bucket list now supports POIs (not just countries): add any place with auto-search via Google Places / Nominatim - Optional target date (month/year) via CustomSelect dropdowns - New target_date field on bucket_list table (DB migration) - Server PUT route supports updating all fields - Country bucket modal: date dropdowns default to empty - CustomSelect: auto-opens upward when near bottom of viewport - Search results open upward in the bucket add form - i18n keys for DE and EN |
||
|
|
cd634093af |
feat: multi-select category filter, performance fixes, check-in/out order
- Category filter is now a multi-select dropdown with checkboxes - PlaceAvatar: replace 200ms polling intervals with event-based notification + React.memo for major performance improvement - Map photo fetches: concurrency limited to 3 + lazy loading on images - PlacesSidebar: content-visibility + useMemo for smooth scrolling - Accommodation labels: check-out now appears before check-in on same day - Timed places auto-sort chronologically when time is added |
||
|
|
8458481950 |
feat: atlas country marking, bucket list, trip creation UX — closes #49
Atlas: - Click any country to mark as visited or add to bucket list - Bucket list with country flags, planned month/year, horizontal layout - Confirm popup with two options (mark visited / bucket list) - Full A2/A3 country code mapping for all countries Trip creation: - Drag & drop cover image support - Add travel buddies via CustomSelect dropdown when creating a trip - Manual date entry via double-click on date picker (supports DD.MM.YYYY, ISO, etc.) |
||
|
|
e78c2a97bd |
v2.6.2 — TREK Rebrand, OSM Enrichment, File Management, Hotel Bookings & Bug Fixes
Rebrand: - NOMAD → TREK branding across all UI, translations, server, PWA manifest - New TREK logos (dark/light, with/without icon) - Liquid glass toast notifications Bugs Fixed: - HTTPS redirect now opt-in only (FORCE_HTTPS=true), fixes #33 #43 #52 #54 #55 - PDF export "Tag" fallback uses i18n, fixes #15 - Vacay sharing color collision detection, fixes #25 - Backup settings import fix (PR #47) - Atlas country detection uses smallest bounding box, fixes #31 - JPY and zero-decimal currencies formatted correctly, fixes #32 - HTML lang="en" instead of hardcoded "de", fixes #34 - Duplicate translation keys removed - setSelectedAssignmentId crash fixed New Features: - OSM enrichment: Overpass API for opening hours, Wikimedia Commons for photos - Reverse geocoding on map right-click to add places - OIDC config via environment variables (OIDC_ISSUER, OIDC_CLIENT_ID, etc.), fixes #48 - Multi-arch Docker build (ARM64 + AMD64), fixes #11 - File management: star, trash/restore, upload owner, assign to places/bookings, notes - Markdown rendering in Collab Notes with expand modal, fixes #17 - Type-specific booking fields (flight: airline/number/airports, hotel: check-in/out/days, train: number/platform/seat), fixes #35 - Hotel bookings auto-create accommodations, bidirectional sync - Multiple hotels per day with check-in/check-out color coding - Ko-fi and Buy Me a Coffee support cards - GitHub releases proxy with server-side caching |
||
|
|
8396a75223 | refactoring: TypeScript migration, security fixes, | ||
|
|
cb080954c9 |
Reservation end time, route perf overhaul, assignment search fix
- Add reservation_end_time field (DB migration, API, UI) - Split reservation form: separate date, start time, end time, status fields - Fix DateTimePicker forcing 00:00 when no time selected - Show end time across all reservation displays - Link-to-assignment and date on same row (50/50 layout) - Assignment search now shows day headers for filtered results - Auto-fill date when selecting a day assignment - Route segments: single OSRM request instead of N separate calls (~6s → ~1s) - Route labels visible from zoom level 12 (was 16) - Fix stale route labels after place deletion (useEffect triggers recalc) - AbortController cancels outdated route calculations |
||
|
|
35275e209d |
Fix double delete confirm, inline place name editing, preserve assignments on trip extend
- Replace double browser confirm() with single custom ConfirmDialog for place deletion - Add inline name editing via double-click in PlaceInspector - Rewrite generateDays() to preserve existing days/assignments when extending trips - Use UTC date math to avoid timezone-related day count errors - Add missing collab.chat.emptyDesc translation (en/de) |
||
|
|
785f0a7684 |
Participants, context menus, budget rename, file types, UI polish
- Assignment participants: toggle who joins each activity - Chips with hover-to-remove (strikethrough effect) - Add button with dropdown for available members - Avatars in day plan sidebar - Side-by-side with reservation in place inspector - Right-click context menus for places, notes in day plan + places list - Budget categories can now be renamed (pencil icon inline edit) - Admin: configurable allowed file types (stored in app_settings) - File manager shows allowed types dynamically - Hotel picker: select place + save button (no auto-close) - Edit pencil opens full hotel popup with all options - Place inspector: opening hours + files side by side on desktop - Address clamped to 2 lines, coordinates hidden on mobile - Category shows icon only on mobile - Rating hidden on mobile in place inspector - Time validation: "10" becomes "10:00" - Climate weather: full hourly data from archive API - CustomSelect: grouped headers support (isHeader) - Various responsive fixes |
||
|
|
e1cd9655fb |
Context menus, climate hourly data, UI fixes
- Right-click context menus for places in day plan (edit, remove, Google Maps, delete) - Right-click context menus for places in places list (edit, add to day, delete) - Right-click context menus for notes (edit, delete) - Historical climate now shows full hourly data, wind, sunrise/sunset (same as forecast) - Day header selected background improved for dark mode - Note input: textarea with 150 char limit and counter - Note text wraps properly in day plan |
||
|
|
763c878dab | Fix PlaceAvatar showing inherited photo from previous place | ||
|
|
0497032ed7 |
v2.5.7: Reservation overhaul, Day Detail Panel, i18n, paste support, auto dark mode
BREAKING: Reservations have been completely rebuilt. Existing place-level reservations are no longer used. All reservations must be re-created via the Bookings tab. Your trips, places, and other data are unaffected. Reservation System (rebuilt from scratch): - Reservations now link to specific day assignments instead of places - Same place on different days can have independent reservations - New assignment picker in booking modal (grouped by day, searchable) - Removed day/place dropdowns from booking form - Reservation badges in day plan sidebar with type-specific icons - Reservation details in place inspector (only for selected assignment) - Reservation summary in day detail panel Day Detail Panel (new): - Opens on day click in the sidebar - Detailed weather: hourly forecast, precipitation, wind, sunrise/sunset - Historical climate averages for dates beyond 16 days - Accommodation management with check-in/check-out, confirmation number - Hotel assignment across multiple days with day range picker - Reservation overview for the day Places: - Places can now be assigned to the same day multiple times - Start time + end time fields (replaces single time field) - Map badges show multiple position numbers (e.g. "1 · 4") - Route optimization fixed for duplicate places - File attachments during place editing (not just creation) - Cover image upload during trip creation (not just editing) - Paste support (Ctrl+V) for images in trip, place, and file forms Internationalization: - 200+ hardcoded German strings translated to i18n (EN + DE) - Server error messages in English - Category seeds in English for new installations - All planner, register, photo, packing components translated UI/UX: - Auto dark mode (follows system preference, configurable in settings) - Navbar toggle switches light/dark (overrides auto) - Sidebar minimize buttons z-index fixed - Transport mode selector removed from day plan - CustomSelect supports grouped headers (isHeader option) - Optimistic updates for day notes (instant feedback) - Booking cards redesigned with type-colored headers and structured details Weather: - Wind speed in mph when using Fahrenheit setting - Weather description language matches app language Admin: - Weather info panel replaces OpenWeatherMap key input - "Recommended" badge styling updated |
||
|
|
384d583628 |
v2.5.0 — Addon System, Vacay, Atlas, Dashboard Widgets & Mobile Overhaul
The biggest NOMAD update yet. Introduces a modular addon architecture and three major new features. Addon System: - Admin panel addon management with enable/disable toggles - Trip addons (Packing List, Budget, Documents) dynamically show/hide in trip tabs - Global addons appear in the main navigation for all users Vacay — Vacation Day Planner (Global Addon): - Monthly calendar view with international public holidays (100+ countries via Nager.Date API) - Company holidays with auto-cleanup of conflicting entries - User-based system: each NOMAD user is a person in the calendar - Fusion system: invite other users to share a combined calendar with real-time WebSocket sync - Vacation entitlement tracking with automatic carry-over to next year - Full settings: block weekends, public holidays, company holidays, carry-over toggle - Invite/accept/decline flow with forced confirmation modal - Color management per user with collision detection on fusion - Dissolve fusion with preserved entries Atlas — Travel World Map (Global Addon): - Fullscreen Leaflet world map with colored country polygons (GeoJSON) - Glass-effect bottom panel with stats, continent breakdown, streak tracking - Country tooltips with trip count, places visited, first/last visit dates - Liquid glass hover effect on the stats panel - Canvas renderer with tile preloading for maximum performance - Responsive: mobile stats bars, no zoom controls on touch Dashboard Widgets: - Currency converter with 50 currencies, CustomSelect dropdowns, localStorage persistence - Timezone widget with customizable city list, live updating clock - Per-user toggle via settings button, bottom sheet on mobile Admin Panel: - Consistent dark mode across all tabs (CSS variable overrides) - Online/offline status badges on user list via WebSocket - Unified heading sizes and subtitles across all sections - Responsive tab grid on mobile Mobile Improvements: - Vacay: slide-in sidebar drawer, floating toolbar, responsive calendar grid - Atlas: top/bottom glass stat bars, no popups - Trip Planner: fixed position content container prevents overscroll, portal-based sidebar buttons - Dashboard: fixed viewport container, mobile widget bottom sheet - Admin: responsive tab grid, compact buttons - Global: overscroll-behavior fixes, modal scroll containment Other: - Trip tab labels: Planung→Karte, Packliste→Liste, Buchungen→Buchung (DE mobile) - Reservation form responsive layout - Backup panel responsive buttons |
||
|
|
fd6fc9e71f |
Fix mobile date picker + auto-update end date from start date (v2.3.4)
- Date picker dropdown stays within viewport on mobile (no more overflow) - Opens above if not enough space below - Centers on very small screens (<360px) - End date auto-adjusts when start date changes: - If no end date or end < start → end = start - If both set → preserves trip duration (shifts end by same delta) |
||
|
|
74f19f3312 |
v2.1.0 — Real-time collaboration, performance & security overhaul
Real-Time Collaboration (WebSocket): - WebSocket server with JWT auth and trip-based rooms - Live sync for all CRUD operations (places, assignments, days, notes, budget, packing, reservations, files) - Socket-based exclusion to prevent duplicate updates - Auto-reconnect with exponential backoff - Assignment move sync between days Performance: - 16 database indexes on all foreign key columns - N+1 query fix in places, assignments and days endpoints - Marker clustering (react-leaflet-cluster) with configurable radius - List virtualization (react-window) for places sidebar - useMemo for filtered places - SQLite WAL mode + busy_timeout for concurrent writes - Weather API: server-side cache (1h forecast, 15min current) + client sessionStorage - Google Places photos: persisted to DB after first fetch - Google Details: 3-tier cache (memory → sessionStorage → API) Security: - CORS auto-configuration (production: same-origin, dev: open) - API keys removed from /auth/me response - Admin-only endpoint for reading API keys - Path traversal prevention in cover image deletion - JWT secret persisted to file (survives restarts) - Avatar upload file extension whitelist - API key fallback: normal users use admin's key without exposure - Case-insensitive email login Dark Mode: - Fixed hardcoded colors across PackingList, Budget, ReservationModal, ReservationsPanel - Mobile map buttons and sidebar sheets respect dark mode - Cluster markers always dark UI/UX: - Redesigned login page with animated planes, stars and feature cards - Admin: create user functionality with CustomSelect - Mobile: day-picker popup for assigning places to days - Mobile: touch-friendly reorder buttons (32px targets) - Mobile: responsive text (shorter labels on small screens) - Packing list: index-based category colors - i18n: translated date picker placeholder, fixed German labels - Default map tile: CartoDB Light |
||
|
|
cb1e217bbe |
Initial commit — NOMAD (Navigation Organizer for Maps, Activities & Destinations)
Self-hosted travel planner with Express.js, SQLite, React & Tailwind CSS. |