refactor: comprehensive consistency review — UI/UX, code quality, functional parity

Fix 19 issues across 3 priority tiers found during full-codebase review:

CRITICAL:
- Fix undefined --color-secondary CSS variable causing invisible UI elements
- Fix Google Photos command templates using nonexistent asset.originalFileName
- Fix scheduler template variable docs (tracker_name → schedule_name)
- Add missing admin guard on notification template update endpoint

HIGH:
- Fix 5 hardcoded English strings missing i18n (MultiEntitySelect, actions,
  settings, TelegramBotTab, users)
- Replace 17 raw <button> elements with shared <Button> component
- Replace 5 raw error divs with shared <ErrorBanner> component
- Refactor webhook handler duplication into shared _dispatch_webhook_event()
- Add 30+ provider-specific fields to TrackingConfig TypeScript type
- Add default TrackingConfig seeds for immich and google_photos
- Add provider-specific command variable docs (Gitea, Planka, NUT, GP, Webhook)

MEDIUM:
- Replace hardcoded hex colors and Tailwind classes with CSS variable tokens
- Remove dead code (unused imports, orphaned check_notification_tracker)
- Fix Svelte 5 patterns ($state for _prevProviderId, remove unnecessary as any)
- Fix inconsistent POST response shape (targets now returns full response)
- Fix Google Photos template dead asset.year branches, clarify album_url docs
This commit is contained in:
2026-03-31 23:27:35 +03:00
parent 6113a0039c
commit 6e51164f8e
29 changed files with 501 additions and 309 deletions
@@ -1,4 +1,4 @@
📸 Latest:
{%- for asset in assets %}
• {{ asset.originalFileName }}{% if asset.year %} ({{ asset.year }}){% endif %}
• {{ asset.filename }}{% if asset.type == 'VIDEO' %} 🎬{% endif %}
{%- endfor %}
@@ -1,4 +1,4 @@
🎲 Random:
{%- for asset in assets %}
• {{ asset.originalFileName }}
• {{ asset.filename }}
{%- endfor %}
@@ -1,4 +1,4 @@
🔍 Results for "{{ query }}":
{%- for asset in assets %}
• {{ asset.originalFileName }}{% if asset.year %} ({{ asset.year }}){% endif %}
• {{ asset.filename }}{% if asset.type == 'VIDEO' %} 🎬{% endif %}
{%- endfor %}
@@ -1,4 +1,4 @@
📸 Последние:
{%- for asset in assets %}
• {{ asset.originalFileName }}{% if asset.year %} ({{ asset.year }}){% endif %}
• {{ asset.filename }}{% if asset.type == 'VIDEO' %} 🎬{% endif %}
{%- endfor %}
@@ -1,4 +1,4 @@
🎲 Случайные:
{%- for asset in assets %}
• {{ asset.originalFileName }}
• {{ asset.filename }}
{%- endfor %}
@@ -1,4 +1,4 @@
🔍 Результаты по запросу "{{ query }}":
{%- for asset in assets %}
• {{ asset.originalFileName }}{% if asset.year %} ({{ asset.year }}){% endif %}
• {{ asset.filename }}{% if asset.type == 'VIDEO' %} 🎬{% endif %}
{%- endfor %}