mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-05-17 10:29:49 -05:00
a72b5476cc
Adds a per-user theme picker under Settings → Custom theme. Users can pick one of eight built-in themes (default, ocean, forest, sunset, lavender, rose, slate, high-contrast) and optionally override accent colour, sidebar style, text size and corner radius. Preferences are persisted on the users table and applied on every page load through a single <style id="tt-theme-vars"> block injected into base.html. The picker (app/templates/components/theme_picker.html) is self- contained vanilla JS: clicks debounce a POST /api/user/theme that returns the regenerated CSS block, so changes preview instantly with no page reload, and only persist when Save is clicked. The default theme generates an empty CSS block, so existing users see zero visual change until they opt in. ThemeService reads every user attribute through getattr() and falls back to defaults on exception, so an unmigrated database never breaks rendering. All values that end up in the generated CSS are validated against the strict #RRGGBB regex or explicit allow-lists before being embedded. - Alembic revision 156_add_user_theme_columns adds five nullable columns to the users table (defensively — each column is only added if missing): theme_name, theme_accent_color, theme_sidebar_style, theme_font_size, theme_border_radius. - ThemeService (app/services/theme_service.py): BUILT_IN_THEMES dict, ACCENT_PRESETS palette, get_theme_css_vars / get_all_themes / validate_accent_color / save_user_theme. - New API: GET / POST /api/user/theme (both @login_required). - New context processor inject_theme exposes theme_css on every request; base.html renders it right after the existing CSS link tags. - Documented in docs/features/CUSTOM_THEMES.md; CHANGELOG and README updated to reflect the feature.