feat(web): theme import/export, more themable colors, hideable local/ical calendars

Theme:
- Export/import themes via UI as <date>_<time>.theme (JSON, readable keys,
  link to THEME.md). Import is partial-aware: only present params are written
  (server accepts partial); prompts before importing files with unknown params.
- Dynamic favicon + theme-color tinted to the primary colour on load/save.
- New themable colours: general hover-highlight, day hover/selected/bg,
  today background, plus two unified sidebar action-icon colours
  (inactive/active) covering bell, hide, delete and read-only icons.
- All new colours are per-setting syncable; documented in THEME.md.

UX:
- Styled confirm dialog (#modal-confirm) replaces window.confirm() for
  calendar delete and account disconnect.
- Birthday/local calendars and iCal subscriptions can now be hidden from the
  sidebar via Settings (new sidebar_hidden column + hide toggle).

Backend: additive nullable columns + idempotent migrations for user_settings
colours and local_calendars/ical_subscriptions.sidebar_hidden.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-07-20 13:20:30 +02:00
parent 12c869451b
commit 6316ed3a6b
15 changed files with 475 additions and 47 deletions

View File

@@ -487,6 +487,24 @@
</div>
</div>
<!-- Generic Confirm Dialog (styled replacement for window.confirm) -->
<div id="modal-confirm" class="modal-overlay hidden">
<div class="modal-card" style="max-width:400px">
<div class="modal-header">
<h3 id="confirm-title">Bestätigen</h3>
<button class="icon-btn modal-close" data-modal="modal-confirm">&times;</button>
</div>
<div class="modal-body">
<p id="confirm-text"></p>
</div>
<div class="modal-footer">
<div style="flex:1"></div>
<button class="btn btn-ghost" id="confirm-cancel" data-modal="modal-confirm" data-i18n="cancel">Abbrechen</button>
<button class="btn btn-danger" id="confirm-ok" data-i18n="delete">Löschen</button>
</div>
</div>
</div>
<!-- Event Detail Popup -->
<div id="popup-event" class="event-popup hidden">
<div class="popup-header">
@@ -815,6 +833,12 @@
<button type="button" class="sync-toggle sync-toggle-lg" id="cfg-sync-all" role="switch" aria-checked="false"></button>
</div>
<div class="settings-table" id="settings-appearance-table"></div>
<div class="theme-io-row">
<button type="button" class="btn btn-secondary btn-sm" id="cfg-theme-export" data-i18n="theme_export">Theme exportieren</button>
<button type="button" class="btn btn-secondary btn-sm" id="cfg-theme-import" data-i18n="theme_import">Theme importieren</button>
<a class="theme-io-help" id="cfg-theme-help" href="https://git.scarriffle.com/Scarriffle/Calendarr/src/branch/beta/THEME.md" target="_blank" rel="noopener noreferrer" data-i18n-title="theme_docs_hint" title="Erklärung der Theme-Parameter">?</a>
<input type="file" id="cfg-theme-file" accept=".theme,application/json,.json" hidden />
</div>
</div>
<!-- Kalender: einheitliche Tabelle aller Kalender aus allen Quellen -->