- settings: hide color-mode icons on mobile, shorten "Automatisch" -> "Auto"
- settings: language picker as custom dropdown on mobile
- admin permissions: reset button icon-only on mobile, sized to match save
- admin places toggles: add flex-shrink-0 + row gap so switches don't collapse
- de: settings.notifications label "Benachrichtigungen" -> "Mitteilungen"
- MCP tokens tab only shown when MCP addon is enabled
- Permissions panel moved from own tab to users tab below invite links
- Fixed inconsistent dropdown widths in permissions panel
Adds a full permissions management feature allowing admins to control
who can perform actions across the app (trip CRUD, files, places,
budget, packing, reservations, collab, members, share links).
- New server/src/services/permissions.ts: 16 configurable actions,
in-memory cache, checkPermission() helper, backwards-compatible
defaults matching upstream behaviour
- GET/PUT /admin/permissions endpoints; permissions loaded into
app-config response so clients have them on startup
- checkPermission() applied to all mutating route handlers across
10 server route files; getTripOwnerId() helper eliminates repeated
inline DB queries; trips.ts and files.ts now reuse canAccessTrip()
result to avoid redundant DB round-trips
- New client/src/store/permissionsStore.ts: Zustand store +
useCanDo() hook; TripOwnerContext type accepts both Trip and
DashboardTrip shapes without casting at call sites
- New client/src/components/Admin/PermissionsPanel.tsx: categorised
UI with per-action dropdowns, customised badge, save/reset
- AdminPage, DashboardPage, FileManager, PlacesSidebar,
TripMembersModal gated via useCanDo(); no prop drilling
- 46 perm.* translation keys added to all 12 language files