Add theming system: custom palettes, per-user colour mode, admin appearance page
- 4 built-in themes (Default, Pastel, High Contrast, Ocean Blue) seeded as JSON files in /config/themes/ on startup; custom themes can be created, edited, and deleted via the new admin Appearance page - All theme tokens applied via JS inline CSS properties (no hardcoded CSS blocks) - New `color_mode` column on users table (migration dd6ad2f2c211); users can override the admin-set global default in Settings - Backend: GET/PATCH /settings/appearance, full CRUD on /settings/themes - Frontend: AdminAppearancePage with theme grid + colour pickers, SettingsPage replaces placeholder with mode selector, useTheme rewritten to fetch from API Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -71,6 +71,7 @@ class UserOut(BaseModel):
|
||||
# validation_alias reads is_superuser from the ORM object; the JSON key
|
||||
# in the response is the field name "is_admin" (not the alias).
|
||||
is_admin: bool = Field(validation_alias="is_superuser", default=False)
|
||||
color_mode: str | None = None
|
||||
|
||||
model_config = {"from_attributes": True, "populate_by_name": True}
|
||||
|
||||
@@ -104,6 +105,17 @@ class DashboardPrefsOut(BaseModel):
|
||||
app_ids: list[str]
|
||||
|
||||
|
||||
class ColorModeUpdate(BaseModel):
|
||||
color_mode: str
|
||||
|
||||
@field_validator("color_mode")
|
||||
@classmethod
|
||||
def validate_mode(cls, v: str) -> str:
|
||||
if v not in ("light", "dark", "system"):
|
||||
raise ValueError("color_mode must be 'light', 'dark', or 'system'")
|
||||
return v
|
||||
|
||||
|
||||
class DashboardPrefsUpdate(BaseModel):
|
||||
app_ids: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user