- Fix i18n: remove $state rune (SSR incompatible in .ts files),
use reactive localeVersion counter in layout to trigger re-render
on locale change. Language switching now works immediately.
- Fix dark theme: add global CSS rules for input/select/textarea to
use theme colors, override browser autofill in dark mode, set
color-scheme for native controls (scrollbars, checkboxes)
- Collapsible sidebar: toggle button (▶/◀) with persistent state,
icons-only mode when collapsed. Theme/language buttons moved to
bottom above user info.
- Loading skeletons: all pages show animated pulse placeholders
while data loads, eliminating content flicker on tab switch
- Edit support: Servers, Trackers, and Targets now have Edit buttons
that open the form pre-filled with current values. Save calls PUT.
Sensitive fields (API key, bot token) can be left empty to keep
current value when editing.
- CLAUDE.md: add dev server restart rules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Frontend enhancements:
- i18n: Full Russian and English translations (~170 keys each),
language switcher in sidebar and login page, auto-detect from
browser, persists to localStorage
- Themes: Light/dark mode with CSS custom properties, system
preference detection, toggle in sidebar header, smooth transitions
- Dark theme: Full color palette (background, card, muted, border,
success, warning, error variants)
Enhanced forms:
- Tracker creation: asset type filtering (images/videos), favorites
only, include people/details toggles, sort by/order selects,
max assets to show
- Target creation: Telegram media settings (collapsible) with
max media, group size, chunk delay, max asset size, URL preview
disable, large photos as documents
- Template creation: event_type selector (all/added/removed/renamed/deleted)
All pages use t() for translations, var(--color-*) for theme-safe
colors, and proper label-for-input associations.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fixes 7 issues identified by code-reviewer agent:
1. (Critical) Move JSON.parse inside try/catch in targets page to
handle malformed webhook headers input gracefully
2. (Low) Add window guard to refreshAccessToken for SSR safety
3. (Important) Show loading indicator instead of page content while
auth state is being resolved (prevents flash of protected content)
4. (Important) Add try/catch to trackers load() Promise.all
5. (Important) Add error handling to remove() in servers, trackers,
and templates pages
6. (Important) Track preview per-template with previewId, show
inline instead of global bottom block
7. (Important) Use finally block for loading state in auth
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Build a modern, calm web UI using SvelteKit 5 + Tailwind CSS v4.
Pages:
- Setup wizard (first-run admin account creation)
- Login with JWT token management and auto-refresh
- Dashboard with stats cards and recent events timeline
- Servers: add/delete Immich server connections with validation
- Trackers: create album trackers with album picker, event type
selection, target assignment, and scan interval config
- Templates: Jinja2 message template editor with live preview
- Targets: Telegram and webhook notification targets with test
- Users: admin-only user management (create/delete)
Architecture:
- Reactive auth state with Svelte 5 runes
- API client with JWT auth, auto-refresh on 401
- Static adapter builds to 153KB for embedding in FastAPI
- Vite proxy config for dev server -> backend API
- Sidebar layout with navigation and user info
Also adds Rule 2 to primary plan: perform detailed code review
after completing each phase.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>